//
// Visuzalization module for TETDM 
// DrawOriginal.java Version 0.30
// Copyright(C) 2011 WATARU SUNAYAMA ALL RIGHTS RESERVED.
//
// This program is provided under the license.
// You should read the README file.
//


package module.VisualizationModules.DrawOriginal;

import source.*;
import source.TextData.*;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;


public class DrawOriginal extends VisualizationModule implements MouseListener, MouseMotionListener
{
	//For objects operation
	int mousex, mousey;			//Coordinates for a mouse
	int old_mousex, old_mousey;	//Last Coordinates for a mosue
	int dx, dy;					//Distance for mouse moving
	
	int touch_num;				//Node Number of being touched
	int oldTouchNumber;
	
	boolean moving;			//Flag for node moving
	boolean dragging;		//Flag for field moving	

	boolean springmodel1;
	Thread th;
	
	int node_keyidlist[];
	int topic_num;
	
	DecimalFormat df_a;
	
	NewMapData2 map;
	
	public DrawOriginal()
	{
		setModuleID(1013);
	}

	public void initializePanel()
	{
		addMouseListener(this);			//MouseListener
		addMouseMotionListener(this);	//MouseMotionListener	
	}	
	
	public void initializeData()
	{
		df_a = new DecimalFormat("0.00");
		
		touch_num = -1;
		
		moving = false;
		dragging = false;
		
		topic_num = 0;
	}
	
	public void displayOperations(int optionNumber)
	{
		switch(optionNumber)
		{
			case 4501:	
			case 0:
				map = new NewMapData2(text.segmentRelation.number);
				
				boolean active[] = new boolean[text.segmentNumber];
				for(int i=0;i<text.segmentNumber;i++)
					active[i] = true;
				
				text.segmentRelation.createStrongestLink(text.segmentRelation.cos);
				//		text.segmentRelation.optimize_link(text.segmentRelation.cos, 0.5);		
				
				map.set_relation_data(text.segmentRelation);				

				repaint();
				break;
				
			case 1:
				saveData();
				break;
		}		
	}

	public void saveData()
	{
		String datafile = "OriginalData";
		String saveFile = myModulePath+datafile;
		String saveData[];
		
		saveData = new String[text.segmentRelation.number];
		
		for(int i=0;i<text.segmentRelation.number;i++)
			saveData[i] = map.node[i].name+" "+map.relation[i][0].value;

		fileWriteArray(saveFile, saveData, saveData.length);			
	}

	//////////DRAWING

	
	void calcu_coordinate()
	{
		for(int i=0;i<text.segmentNumber;i++)
		{
			map.node[i].x *= changeX;
			map.node[i].y *= changeY;
		}
	}	
	
	void draw_background(Graphics2D g2)
	{
        g2.setColor(new Color(0,128,255));
        g2.fillRect(0,0, sizeX, (int)(sizeY*0.5));
		
        g2.setColor(Color.yellow);
        g2.fillRect(0,(int)(sizeY*0.5), sizeX, (int)(sizeY*0.75));
		
        g2.setColor(Color.red);
        g2.fillRect(0,(int)(sizeY*0.75), sizeX, sizeY);

	}

	//Display links
	public void draw_links(Graphics2D g2)
	{
		g2.setColor(Color.white);
		g2.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER));
		for(int i=0;i<map.node_num;i++)
			for(int j=0;j<map.node_num;j++)
				if(map.relation[i][j].link == true)
					g2.drawLine((int)map.node[i].x,(int)map.node[i].y,(int)map.node[j].x,(int)map.node[j].y);
	}
	
	
	//Display nodes
	public void draw_node(Graphics2D g2, int n)
	{
		g2.setColor(map.node[n].color);
		g2.fillOval((int)map.node[n].x - (int)map.node[n].radius, 
						(int)map.node[n].y - (int)map.node[n].radius, (int)map.node[n].radius*2, (int)map.node[n].radius*2);
	}
	
	public void draw_nodes(Graphics2D g2)
	{
		for(int i=0;i<map.node_num;i++)
			draw_node(g2, i);
	}
	
	////Dispaly node names
	public void draw_node_name(Graphics2D g2, int n)
	{
		g2.setFont(new Font("Dialog", Font.BOLD, (int)(text.fontSize+10-2*map.node_num/25.0)));
//		g2.drawString(map.node[n].name+":"+(int)(map.relation[n][0].value*100), (int)map.node[n].x+(int)map.node[n].radius, (int)map.node[n].y+(int)map.node[n].radius);
		g2.drawString(map.node[n].name, (int)map.node[n].x+(int)map.node[n].radius, (int)map.node[n].y+(int)map.node[n].radius);		
	}
	
	public void draw_node_names(Graphics2D g2)
	{		
		for(int i=0;i<map.node_num;i++)
		{
			g2.setColor(Color.black);
			draw_node_name(g2, i);
		}
	}	
	
	public void draw_touch_node(Graphics2D g2)
	{
		if(text.focus.mainFocusSegment < 0)
			return;
		
		draw_node(g2, text.focus.mainFocusSegment);
	}
	
	//Display node names touched by a mouse
	public void draw_touch_nodename(Graphics2D g2)
	{
		if(text.focus.mainFocusSegment < 0)
			return;
	
		int i=text.focus.mainFocusSegment, j=text.segmentRelation.rank[text.focus.mainFocusSegment][1];
		
		g2.setColor(Color.white);
		g2.setStroke(new BasicStroke(5, BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER));
		g2.drawLine((int)map.node[i].x,(int)map.node[i].y,(int)map.node[j].x,(int)map.node[j].y);		
		
		
		g2.setColor(Color.red);
		draw_node_name(g2, i);
		draw_node_name(g2, j);
	}


	
	void draw_for_linkage(Graphics2D g2)
	{
		for(int i=0;i<map.node_num;i++)
			if(text.focus.focusKeywords[i])			
			{
				g2.setColor(Color.white);
				draw_node_name(g2, i);
			}
		
		if(text.focus.mainFocusSentence >= 0)
		{
			g2.setColor(Color.red);
			draw_node_name(g2, text.focus.mainFocusSentence);
		}	
	}	
	
	public void paintComponent(Graphics g)
	{
		
		Graphics2D g2 = (Graphics2D)g;
		
		boolean change = getPanelSize();		
		
		if(change)
			calcu_coordinate();
		
		draw_background(g2);	//Set background
		draw_links(g2);			//Display links
		draw_nodes(g2);			//Display nodes
		draw_node_names(g2);	//Display node names
		draw_touch_node(g2);	//Display nodes touched by a mouse
		draw_touch_nodename(g2);	//Display node names touched by a mouse
//		draw_parameters(g2);	//Display parameters
		
		draw_for_linkage(g2);
	}
	
	public void update(Graphics g)		//Avoid from blinking
	{
		paintComponent(g);
	}
	
	//MouseListener
	public void mousePressed(MouseEvent me)	//Press
	{
		mousex = me.getX();
		mousey = me.getY();
		
		if(touch_num == -1)
		{
			old_mousex = mousex;
			old_mousey = mousey;
			dragging = true;
			return;
		}
		moving = true;
	}
	
	public void mouseReleased(MouseEvent me)	//Release
	{
		if(moving == true)
			moving = false;
		
		if(dragging == true)
			dragging = false;
	}
	
	public void mouseEntered(MouseEvent me){}	//Enter an area
	public void mouseExited(MouseEvent me){}	//Exit an area
	


	public void mouseClicked(MouseEvent me)	//Click
	{
		int click_num;
		
		mousex = me.getX();
		mousey = me.getY();
		click_num = CatchNode(mousex,mousey);
		
		if(click_num == -1)
		{
			topic_num = 0;
			for(int i=0;i<map.node_num;i++)
				if(map.node[i].y < 30*sizeY/100)
					topic_num++;

			node_keyidlist = new int[topic_num];
			
			int c=0;
			for(int i=0;i<map.node_num;i++)
				if(map.node[i].y < 30*sizeY/100)				
					node_keyidlist[c++] = map.node[i].id;

//			pvs1.indica.setSelected(true);
	//		mining.set_data(node_keyidlist);//FEEDBACK
	//		mining.module_options(0);			//
	//		mining.module_options(1);			//
			System.out.println("Clicked!!");			
//			init_data();
		}
		repaint();
	}	
	
	//MouseMotionListener
	public void mouseDragged(MouseEvent me)	//Dragging
	{
		if(moving == true)		//Move a node
		{
			try{
				mousex = me.getX();
				mousey = me.getY();
				
				map.node[touch_num].x = mousex;
				map.node[touch_num].y = mousey;
				
				repaint();
			}
			catch(StackOverflowError e){
				System.out.println("Stack OVERFLOW");
			}
		}
		
		if(dragging == true)	//Move Field
		{
			mousex = me.getX();
			mousey = me.getY();
			dx = old_mousex - mousex;
			dy = old_mousey - mousey;
			old_mousex = mousex;
			old_mousey = mousey;
			
			for(int i=0;i<map.node_num;i++)
			{
				map.node[i].x -= dx;
				map.node[i].y -= dy;
			}
			repaint();
		}
	}
	
	public void mouseMoved(MouseEvent me)
	{
		mousex = me.getX();
		mousey = me.getY();
		touch_num = CatchNode(mousex,mousey);

		if(touch_num >= 0)
		{
			text.focus.mainFocusSegment = touch_num;
			text.focus.subFocusSegment = text.segmentRelation.rank[touch_num][1];//
			
			if(touch_num != oldTouchNumber)
			{
				repaintOthersByTouch();
				executeAllByTouch();
				oldTouchNumber = touch_num;
			}
		}
		repaint();
	}
	
	public int CatchNode(int mousex, int mousey)	//Investigate number of selected node
	{
		for(int i=0;i<map.node_num;i++)
			if((mousex > map.node[i].x - map.node[i].radius && mousex < map.node[i].x + map.node[i].radius 
												+ map.node[i].name.length()*(24-2*map.node_num/25.0)) && 
			   (mousey > map.node[i].y - map.node[i].radius && mousey < map.node[i].y + map.node[i].radius))
				return i;
	 
		return -1;
	}

	class NewMapData2
	{
		
		class Node
		{
			String name;
			int id;
		
			double x;
			double y;
			double radius=10;
			
			int link_num;
		
			Color color;
		}
	
		Node node[];
		int node_num;
	
	
		//Node Relation Class
		class Relation
		{
			boolean link;			//Is exist a link between nodes?
			double value;
		}
	
		Relation relation[][];		//Node Relation information	

		NewMapData2(int num)
		{
			init_nodes(num);
		}		
		
		void init_nodes(int num)
		{
			node_num = num;
			node = new Node[node_num];
		
			for(int i=0;i<node_num;i++)
				node[i] = new Node();
		
			relation = new Relation[node_num][node_num];

			for(int i=0;i<node_num;i++)
				for(int j=0;j<node_num;j++)
					relation[i][j] = new Relation();
		}

		void set_relation_data(RelationalData rd)
		{
			for(int i=0;i<node_num;i++)
				for(int j=0;j<node_num;j++)
				{
					relation[i][j].link = rd.link[i][j];
					relation[i][j].value = rd.value[i];				
				}
			
			for(int i=0;i<node_num;i++)
			{
				node[i].id = i;
				node[i].name = rd.name[i];
				node[i].x = sizeX/2 + (sizeX/2-50) * Math.cos(i);
				node[i].y = relation[i][0].value * sizeY;
				node[i].color = new Color(0xff,0x66,0x00);			
			}			
		}
	}
}
