package View;

import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

import Algorithms.Animated.Action;
import Algorithms.Animated.AnimationController;
import Algorithms.Animated.BK.BKNodePlacement;
import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
import IO.Writer;
import Model.LayeredGraphEdge;
import Model.LayeredGraphNode;

/**
 * The main window of the application.
 * @author kolja
 *
 */
public class MainView {
    /**
     * The 'frame' of the main window.
     */
	public static JFrame frame;
	AnimationController controller;
	
	private String strToLen( String s, int l )
	{
		while( s.length() < l )
		{
			s = " " + s + " ";
		}
		if( s.length() > l )
			return s.substring( 0, l );
		return s;
	}
	
	/**
	 * Initialize the window and its contents.
	 * @param graph the graph that is displayed in this window.
	 */
	public MainView( LayeredGraphNode graph )
	{
		controller = new AnimationController();
		controller.setTimeBetween( 10 );
		frame = new JFrame();
        frame.setSize( Math.min( (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200, 1700 ), Math.min( (int)graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200, 900 ) );
		frame.setLocation( 100, 100 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setVisible( true );
		
		frame.addKeyListener( new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void keyPressed(KeyEvent e) {
                if( e.getKeyCode() == KeyEvent.VK_S )
                {
                    Writer w = new Writer( "save.json" );
                    w.writeOutputGraph( graph );
                }
                if( e.getKeyCode() == KeyEvent.VK_LEFT )
                	controller.setNextAction( Action.BACKWARD );
                if( e.getKeyCode() == KeyEvent.VK_RIGHT )
                	controller.setNextAction( Action.FORWARD );
                if( e.getKeyCode() == KeyEvent.VK_P )
                	controller.setContinuous( !controller.isContinuous() );
        		frame.validate();
        		if( e.getKeyCode() == KeyEvent.VK_D )
        		{
        			System.out.println( "Debug Information Table: " );
        			System.out.println( "_______________________________________________________________________________________________________________________________________________________________________________________________________________________" );
        			System.out.println( "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + strToLen( "Bottom -> Top :> Right", 51 ) + "|" );
        			System.out.println( "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|" );
        			System.out.println( "| Node | Shift | Sink | Root | Align |  x  |  xDef  | | Node | Shift | Sink | Root | Align |  x  |  xDef  | | Node | Shift | Sink | Root | Align |  x  |  xDef  | | Node | Shift | Sink | Root | Align |  x  |  xDef  |" );
        			for( LayeredGraphNode n : graph.getContainedNodes() )
        			{
        				System.out.println( "|" + strToLen( n.getName(), 6 ) + 
		        						    "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_LEFT ) + "", 7 ) + 
		        						    "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_LEFT ).getName(), 7 ) + 
		        						    "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_LEFT ) + "", 5 ) + 
		        						    "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_LEFT ) + "", 8 ) + "| " +
		        						    "|" + strToLen( n.getName(), 6 ) + 
		        						    "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_RIGHT ) + "", 7 ) + 
		        						    "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 7 ) + 
		        						    "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_RIGHT ) + "", 5 ) + 
		        						    "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_RIGHT ) + "", 8 ) + "| " +
		        						    "|" + strToLen( n.getName(), 6 ) + 
		        						    "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_LEFT ) + "", 7 ) + 
		        						    "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_LEFT ).getName(), 7 ) + 
		        						    "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_LEFT ) + "", 5 ) + 
		        						    "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_LEFT ) + "", 8 ) + "| " +
		        						    "|" + strToLen( n.getName(), 6 ) + 
		        						    "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_RIGHT ) + "", 7 ) + 
		        						    "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) + 
		        						    "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) + 
		        						    "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) + 
		        						    "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 8 ) + "|");
        			}
        			System.out.println( "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" );
        		}
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub
                
            }
		    
		});
		
		frame.setLayout(new GridLayout( 2, 2, 10, 10 ));
		frame.add(createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT ));
        frame.add(createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT ));
        frame.add(createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT ));
        frame.add(createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT ));
		frame.validate();
		frame.repaint();
		new BKNodePlacement( controller, graph );
	}
	
	private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt )
	{
		NodeView graphView = new NodeView( gNode, lt );
		graphView.setLayout( null );
		graphView.setOpaque( true );
		for( LayeredGraphNode n : gNode.getContainedNodes() )
		{
		    NodeView nv = createNodeView( n, lt );
		    nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
			graphView.add( nv );
		}
        for( LayeredGraphEdge e : gNode.getContainedEdges() )
        {
            EdgeView ev = new EdgeView( e, lt );
            ev.setOpaque( true );
            graphView.add( ev );
        }
		return graphView;
	}
}
