package ui.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

import classes.AbstractCanvasObject;

import classes.Node;

import ui.controller.Control;

import ui.model.Consumer;
import ui.model.DecoratedCable;
import ui.model.DecoratedHolonObject.HolonObjectState;
import utility.ImageImport;
import ui.model.DecoratedNetwork;
import ui.model.DecoratedState;
import ui.model.DecoratedSwitch;
import ui.model.MinimumNetwork;
import ui.model.Model;
import ui.model.Passiv;
import ui.model.Supplier;






public class Outliner extends JFrame {
	private static final long serialVersionUID = 1L;
	JTabbedPane tabbedPane = new JTabbedPane();
	JPanel listPanel = new JPanel(new BorderLayout());
	JPanel statePanel = new JPanel(new BorderLayout());
	public boolean isClosed = false;
	ArrayList<MinimumNetwork> list;
	Outliner(JFrame parentFrame, Model model, Control controller){ 
		setBounds(0, 0, 400, parentFrame.getHeight());
		this.setIconImage(ImageImport.loadImage("/Images/Holeg.png", 30, 30));
		this.setTitle("Outliner");
		setLocationRelativeTo(parentFrame);
		this.setVisible(true);
		repaintWithDecoratedState(controller.getSimManager().getActualDecorState());
		this.getContentPane().add(tabbedPane);
		this.addWindowListener(new java.awt.event.WindowAdapter() {
		    @Override
		    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
		    	isClosed = true;
		    }
		});
		tabbedPane.addTab("List", listPanel);
		tabbedPane.addTab("State", statePanel);
	}

	public void repaintWithDecoratedState(DecoratedState decoratedState) {
		//tabbedPane.removeAll();
		listPanel.removeAll();
		statePanel.removeAll();
		DefaultMutableTreeNode topListPanel = new DefaultMutableTreeNode();
		DefaultMutableTreeNode objects = new DefaultMutableTreeNode("HolonObjects");
		DefaultMutableTreeNode switches = new DefaultMutableTreeNode("Switches");
		DefaultMutableTreeNode nodes = new DefaultMutableTreeNode("Nodes");
		DefaultMutableTreeNode cables = new DefaultMutableTreeNode("Cable");
		topListPanel.add(objects);
		topListPanel.add(switches);
		topListPanel.add(nodes);
		topListPanel.add(cables);
		DefaultMutableTreeNode topStatePanel = new DefaultMutableTreeNode();
		
		for(DecoratedSwitch dSwitch: decoratedState.getDecoratedSwitches()) {
			switches.add(new DefaultMutableTreeNode(dSwitch.getModel().getName()));
		}
		
		/*for(CpsNode node: decoratedState.getNodeList()) {
			nodes.add(new DefaultMutableTreeNode(node.getName()));
		}*/
		
		for(DecoratedNetwork dNet: decoratedState.getNetworkList()) {
			DefaultMutableTreeNode network = new DefaultMutableTreeNode("Network");
			if(!dNet.getConsumerList().isEmpty() || !dNet.getConsumerSelfSuppliedList().isEmpty()) {
				DefaultMutableTreeNode consumer = new DefaultMutableTreeNode("ConsumerList");
				for (Consumer con : dNet.getConsumerList()) {
					DefaultMutableTreeNode consumerNode = new ColoredTreeNode(con.toString(),con.getState().toString(), getStateColor(con.getState()) );
					consumer.add(consumerNode);
					objects.add(new DefaultMutableTreeNode(con.getModel().getName()));
				}
				for (Consumer con : dNet.getConsumerSelfSuppliedList()) {
					DefaultMutableTreeNode consumerNode = new DefaultMutableTreeNode(con.toString() + con.getState());
					consumer.add(consumerNode);
					objects.add(new DefaultMutableTreeNode(con.getModel().getName()));
				}
				network.add(consumer);
			}
			if(!dNet.getSupplierList().isEmpty()) {
				DefaultMutableTreeNode supplier = new DefaultMutableTreeNode("SupplierList");
				for (Supplier sup : dNet.getSupplierList()) {
					supplier.add(new DefaultMutableTreeNode(sup.toString()));
					objects.add(new DefaultMutableTreeNode(sup.getModel().getName()));
				}
				network.add(supplier);
			}
			for(Passiv pas: dNet.getPassivNoEnergyList()) {
				objects.add(new DefaultMutableTreeNode(pas.getModel().getName()));
			}
			topStatePanel.add(network);
			for(DecoratedCable cable : dNet.getDecoratedCableList()) {
				cables.add(new DefaultMutableTreeNode(cable.getModel().toString()));
			}
		}
		
		for(DecoratedCable cable : decoratedState.getLeftOverEdges()) {
			cables.add(new DefaultMutableTreeNode(cable.getModel().toString()));
		}
		
		
		JTree listTree = new JTree(topListPanel);
		signIconsForTree(listTree);
		listTree.setRootVisible(false);
		for (int i = 0; i < listTree.getRowCount(); i++) {
			listTree.expandRow(i);
		}
		JScrollPane listScroller = new JScrollPane(listTree);
		listPanel.add(listScroller);
		
		JTree stateTree = new JTree(topStatePanel);
		signIconsForTree(stateTree);
		stateTree.setRootVisible(false);
		for (int i = 0; i < stateTree.getRowCount(); i++) {
			stateTree.expandRow(i);
		}
		statePanel.add(new JScrollPane(stateTree));
		
		listPanel.revalidate();;
		statePanel.revalidate();
		listPanel.repaint();
	}






	private void signIconsForTree(JTree t) {
		ImageIcon ClosedIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/Close.png",9,9));
		ImageIcon OpenIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/Open.png",9,9));
		ImageIcon LeafIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/Leaf.png",9,9));
		if (ClosedIcon != null && OpenIcon != null && LeafIcon!= null) {
		    DefaultTreeCellRenderer renderer = 
		        new DefaultTreeCellRenderer();
		    renderer.setClosedIcon(ClosedIcon);
		    renderer.setOpenIcon(OpenIcon);
		    renderer.setLeafIcon(LeafIcon);
		    t.setCellRenderer(renderer);
		}
	}
	
	class MyTreeModelListener implements TreeModelListener {

		@Override
		public void treeNodesChanged(TreeModelEvent tmE) {
			// TODO Auto-generated method stub
			System.out.println("treeNodesChanged");
		}

		@Override
		public void treeNodesInserted(TreeModelEvent tmE) {
			// TODO Auto-generated method stub
			System.out.println("treeNodesInserted");
		}

		@Override
		public void treeNodesRemoved(TreeModelEvent tmE) {
			// TODO Auto-generated method stub
			System.out.println("treeNodesRemoved");
		}

		@Override
		public void treeStructureChanged(TreeModelEvent tmE) {
			// TODO Auto-generated method stub
			System.out.println("treeStructureChanged");
		}
	
	}
	private Color getStateColor(HolonObjectState state) {
		switch(state) {
		case NOT_SUPPLIED:
			return new Color(230, 120, 100);
		case NO_ENERGY:
			return Color.white;
		case OVER_SUPPLIED:
			return new Color(166, 78, 229);
		case PARTIALLY_SUPPLIED:
			return Color.yellow;
		case PRODUCER:
			return Color.lightGray;
		case SUPPLIED:
			return new Color(13, 175, 28);
		default:
			return Color.BLACK;
		}
	}
	
	
	@SuppressWarnings("serial")
	class ColoredTreeNode extends DefaultMutableTreeNode{
		private Color color;
		public ColoredTreeNode(String string, String state, Color color) {
			//"<html>Some text <font color='red'>" + "bla" + "some text in red</font></html>"
			//Integer.toHexString(color.getRGB()).substring(2)
			//String c = string + "<html><font bgcolor='#132122'>" + state +"</font></html>";
			super(( "<html>" + string + "<font bgcolor='#" + Integer.toHexString(color.getRGB()).substring(2) + "'>" + state +"</font></html>"));
			//this.color = color;
		}
		public Color getColor(){
			return color;
		}
		public void setColor(Color color) {
			this.color = color;
		}
		
	}
	
	class AbstractCpsObjectInfo {
		private AbstractCanvasObject aCps;
		AbstractCpsObjectInfo(AbstractCanvasObject aCps){
			this.aCps = aCps;
		}
		@Override
		public String toString(){
			return aCps.getName() + " Id:"+ aCps.getId();
		}
		
		public AbstractCanvasObject getAbstractCpsObject()
		{
			return aCps;
		}
	}
}
