package org.kne.cloud.network.klalb.ui;

import java.awt.Color;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import org.kne.cloud.network.MultiProtocolSocketAddress;
import org.kne.cloud.network.ipv6.IPv6Address;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;

public class NetworkGraphPanel extends GraphPanel {
	private KLALBController controller;
	private KLALBStateGUI3 klbgui;
	
	public NetworkGraphPanel(KLALBController controller,KLALBStateGUI3 klbgui) {
		super();
		this.controller = controller;
		this.klbgui=klbgui;
	}
	
	public NetworkGraphPanel(KLALBController kc) {
		this(kc,null);
	}

	private  class InetGraphNode extends GraphNode{

		private IPv6Address address;
		private JPopupMenu popupMenu;

		public InetGraphNode() {
			super();
			initign();
		}

		public InetGraphNode(IPv6Address address, Color color, double x, double y, boolean ismarked) {
			super(getText(address), color, x, y, ismarked);
			this.address=address;
			initign();
		}

		private void initign() {
			popupMenu = new JPopupMenu();
		
			JMenuItem mcpyitm = new JMenuItem(UIEnv.getRsb().getString("copyvirtualaddress"));
			mcpyitm.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(address.toString()), null);
				}
			});
			popupMenu.add(mcpyitm);
			
		JMenuItem ninfom = new JMenuItem(UIEnv.getRsb().getString("nodeinf"));
		ninfom.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				openInformation();
			}
		});
		popupMenu.add(ninfom);
		
			JMenuItem kperfitm = new JMenuItem(UIEnv.getRsb().getString("speedtest"));
			kperfitm.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					KperfGUI kpfg=new KperfGUI();
					kpfg.setVisible(true);
					MultiProtocolSocketAddress source=new MultiProtocolSocketAddress("KLALB_Stream",controller.getIpv6Router().getLocator().getAddress().toString(),0);
					MultiProtocolSocketAddress target=new MultiProtocolSocketAddress("KLALB_Stream", address.toString(), 4564);
					kpfg.setTarget(target,source);
				}
			});
		popupMenu.add(kperfitm);
		
		
			addMouseListener(new MouseListener() {
				
				@Override
				public void mouseReleased(MouseEvent e) {
					if(e.getButton()==MouseEvent.BUTTON3)
						popupMenu.show(NetworkGraphPanel.this,e.getX(),e.getY());
				}
				
				@Override
				public void mousePressed(MouseEvent e) {
					// TODO 自动生成的方法存根
					
				}
				
				@Override
				public void mouseExited(MouseEvent e) {
					// TODO 自动生成的方法存根
					
				}
				
				@Override
				public void mouseEntered(MouseEvent e) {
					// TODO 自动生成的方法存根
					
				}
				
				@Override
				public void mouseClicked(MouseEvent e) {
					if(e.getClickCount()==2&&e.getButton()==MouseEvent.BUTTON1) {
						openInformation();
					}
				}
			});
		}

		protected void openInformation() {
			Image cimg=getCurrentImage();
			NodeInformationPanel pan=new NodeInformationPanel(controller, address,cimg.getScaledInstance(cimg.getWidth(null)/5, cimg.getHeight(null)/5, Image.SCALE_SMOOTH));
			klbgui.addNodeInformationPanel(pan);
		}

	

		private static String getText(IPv6Address address2) {
			return address2.toCompressedString();
		}

		public IPv6Address getAddress() {
			return address;
		}

		public void setAddress(IPv6Address address) {
			this.address = address;
			super.setText(getText(address));
		}
		
	}

	private double nsPerPixel=1000L;
	private class InetGraphEdgeGroup extends GraphEdgeGroup{
		public InetGraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
			super(nodeA, nodeB);
		}

		public void updateLength() {
		long mindelay=Long.MAX_VALUE>>2;
		for (Iterator<GraphEdge> iterator = getEdges().iterator(); iterator.hasNext();) {
			GraphEdge graphEdge = (GraphEdge) iterator.next();
			mindelay=Math.min(mindelay,  graphEdge.linkPath.getDelay());
		}
		setLength(mindelay/nsPerPixel);
	}
	}
	protected void loadNodes() {
		Map<IPv6Address, Long> addr= controller.getIpv6Router().getKlalbRouteProtol().getAddresses();
		Set<IPv6Address> ks=addr.keySet();
		for (Iterator<IPv6Address> iterator = ks.iterator(); iterator.hasNext();) {
			IPv6Address inet6Address = (IPv6Address) iterator.next();
			if(!getNodes().containsKey(inet6Address)) {
				Vector2 v2pos=super.getRandomPos();
				getNodes().put(inet6Address,new InetGraphNode(inet6Address,Color.BLACK,v2pos.x,v2pos.y,inet6Address.equals(controller.getIpv6Router().getLocator().getAddress())));
			}
			}
		Set<IPv6Address> kns=getNodes().keySet();
		for (Iterator<IPv6Address> iterator = kns.iterator(); iterator.hasNext();) {
			IPv6Address inet6Address = (IPv6Address) iterator.next();
			if(!addr.containsKey(inet6Address)) {
				iterator.remove();
			}
		}
		//System.out.println("------------------------------------");
		synchronized (getEdgeGroups()) {
			
		getEdgeGroups().clear();
		Map<IPv6Address, List<LinkDirection>> addr1= controller.getIpv6Router().getKlalbRouteProtol().getPaths();
		Set<Entry<IPv6Address, List<LinkDirection>>> salink=addr1.entrySet();
		for (Iterator<Entry<IPv6Address, List<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
			Entry<IPv6Address, List<LinkDirection>> entry = (Entry<IPv6Address, List<LinkDirection>>) iterator.next();
			List<LinkDirection>lps=entry.getValue();
			for (Iterator<LinkDirection> iterator2 = lps.iterator(); iterator2.hasNext();) {
				LinkDirection linkPath = (LinkDirection) iterator2.next();
				//System.out.println(linkPath);
				InetGraphNode nfrom=(InetGraphNode) getNodes().get(linkPath.getFromLocator());
				InetGraphNode nto=(InetGraphNode) getNodes().get(linkPath.getToLocator());
				if(nfrom!=null&&nto!=null) {
				GraphEdgeGroup group=getGroup(nfrom, nto);
				
				
				GraphEdge ge=new GraphEdge(nfrom,nto,linkPath);
				group.getPaths().add(ge);
				}
			}
		}
		for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
			GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
			((InetGraphEdgeGroup) graphEdgeGroup).updateLength();
		}
		}
		super.loadNodes();
	}
	
	private GraphEdgeGroup getGroup(InetGraphNode a,InetGraphNode b) {
		for (Iterator<GraphEdgeGroup> iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
			GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
			if(graphEdgeGroup.match(a,b)) {
				return graphEdgeGroup;
			}
		}
		GraphEdgeGroup ng=new InetGraphEdgeGroup(a, b);
		IPv6Address aprev= controller.getIpv6Router().getKlalbRouteProtol().getDijkstraPrevNode( a.getAddress());
		IPv6Address bprev= controller.getIpv6Router().getKlalbRouteProtol().getDijkstraPrevNode( b.getAddress());
		
		if( b.getAddress().equals(aprev)||a.getAddress().equals(bprev)) {
		ng.setShortest(true);
		}
		getEdgeGroups().add(ng);
		return ng;
	}


}
