
//
// Visuzalization module for TETDM
// KeywordCompare.java Version 0.36
// Copyright(C) 2012 - 2013 WATARU SUNAYAMA ALL RIGHTS RESERVED.
//
// This program is provided under the license.
// You should read the README file.
//

package module.VisualizationModules.KeywordCompare;

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

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 KeywordCompare extends VisualizationModule// implements ActionListener
{
//    boolean dataNameA[], dataNameB[];
    int dataA[], dataB[];
    int dataNumberA, dataNumberB;
    
    boolean checkDataA, checkDataB;
    
    int segmentNumberA, segmentNumberB;
    double chiSquare[];
    boolean sideA[];
    
    
    int leftCount, rightCount, centerCount;
    int leftMax = 30, rightMax = 30, centerMax = 30;

    int leftSortValue[], leftSortedIndex[];
    int rightSortValue[], rightSortedIndex[];
    int centerSortValue[], centerSortedIndex[];
    
    int keywordID;  //For Attention
    
	public KeywordCompare()
	{
		setModuleID(21);			// Set your module ID after you have got it
		setCategoryID(4);
        setUseMode(0);
        dataNumbers = new int[]{0,0,0,0,    // b,i,d,S
            0,2,0,0,    // bA,iA,dA,SA
            0,0,0};     // bA2,iA2,dA2
		setToolType(2);		
	}
	
	public void initializePanel(){}
	
	public void initializeData()
    {
        dataNumberA = dataNumberB = 0;
        checkDataA = checkDataB = false;
        
        initializeFocusKeywords();
        initializeAttentionKeywords();
        
        segmentNumberA = segmentNumberB = 0;
    }
	
    public double calculateChiSquare(int n) // segment frequency
    {
        if(segmentNumberA + segmentNumberB == 0)
            return 0.0;
        
//        System.out.println(segmentNumberA+"-segment-"+segmentNumberB);
        
        double probA = segmentNumberA/(double)(segmentNumberA + segmentNumberB);
        double probB = segmentNumberB/(double)(segmentNumberA + segmentNumberB);
        double expectA = (dataA[n] + dataB[n]) * probA;
        double expectB = (dataA[n] + dataB[n]) * probB;
        double chiA = (dataA[n] - expectA) * (dataA[n] - expectA) / expectA;
        double chiB = (dataB[n] - expectB) * (dataB[n] - expectB) / expectB;
        
        if(dataA[n] > expectA)
        {
            sideA[n] = true;
            return (chiA + chiB);
        }
        else
        {
            sideA[n] = false;
            return -(chiA + chiB);
        }
    }
    
	public void displayOperations(int optionNumber)
	{
		switch(optionNumber)
		{
			case 4500:
            case 0:
                focusKeywords = getFocusKeywords();
				repaint();
				break;
                
                
            case 9:
                initializeAttentionKeywords();
                break;
                
            case 12:
                setAttentionKeywords();
                break;
		}
	}
	
	public boolean setData(int dataID, int data[])
	{
        if(data.length != text.keywordNumber)
            return false;
        
        switch(dataID)
        {
            case 0:	dataA = data;
                if(dataNumberA == 0)
                    dataNumberA = dataA.length;
                
                if(checkDataA == false && checkDataB == true)
                    createChiSquareIndex();
                //                    createIndex();
                
                checkDataA = true;

				repaint();
                return true;
                
            case 1:	dataB = data;
                if(dataNumberB == 0)
                    dataNumberB = dataB.length;
                
                checkDataB = true;
                if(checkDataA == true)
                    createChiSquareIndex();
//                    createIndex();
                
				repaint();
                return true;
                
            case 10: dataA = data;
                if(dataNumberA == 0)
                    dataNumberA = dataA.length;
                
                checkDataA = true;
                return true;
                
            case 11: dataB = data;   //should be called after case 10
                if(dataNumberB == 0)
                    dataNumberB = dataB.length;
                
                checkDataB = true;
                    createChiSquareIndex();
                
                if(rightCount > 0)
                {
                    attentionKeywords[keywordID] = true;
                }
                
                return true;
        }
        
		return false;
	}
    
    public boolean setData(int dataID, int data)
    {
        switch(dataID)
        {
            case 0: segmentNumberA = data;
                return true;
                
            case 1: segmentNumberB = data;
                return true;
                
            case 10: segmentNumberA = data;     //should be matched with the number of setData(int [])
                return true;
                
            case 11: segmentNumberB = data;     //should be matched with the number of setData(int [])
                return true;
                
            case 12: keywordID = data;
                return true;
        }
        return false;
    }
    

	
    //	public void setFont(){}
	
	//background
	public void drawBackground(Graphics2D g2)
	{
        g2.setColor(Color.white);
        g2.fillRect(0,0, sizeX, sizeY);
        
        //left
        g2.setColor(new Color(0xff,0xf6,0x8f));//(152,251,152));
        g2.fillRoundRect( sizeX * 2/100, sizeY * 4/100, sizeX * 33/100, sizeY * 92/100, 10, 10);
        
        //right
        g2.setColor(new Color(0x54,0xff,0x94));//(255,181,197));
        g2.fillRoundRect( sizeX * 65/100, sizeY * 4/100, sizeX * 33/100, sizeY * 92/100, 10, 10);
        
        //center right
        g2.setColor(new Color(1.0f,1.0f,0.58f,0.8f));//(105,139,34));
        g2.fillRoundRect( sizeX * 33/100, sizeY * 4/100, sizeX * 30/100, sizeY * 92/100, 10, 10);
        
        //center left
        g2.setColor(new Color(0.76f,1.0f,0.76f,0.6f));//(205,105,201));//(188,143,143));
        g2.fillRoundRect( sizeX * 35/100, sizeY * 4/100, sizeX * 30/100, sizeY * 92/100, 10, 10);
	}
	

	
	//////////paint
	public void paintComponent(Graphics g)
	{
		Graphics2D g2 = (Graphics2D)g;
		
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// Anti aliasing
		g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);		
        
		getPanelSize();
        
		drawBackground(g2);		//background
        
        if(checkDataA == false || checkDataB == false)
            return;
        
		drawWords(g2);

	}
	
	public void update(Graphics g)		//avoid from blinking
	{
		paintComponent(g);
	}
    
    public void drawWords(Graphics2D g2)
    {
        String displayString;
        
        g2.setFont(new Font(text.getFontName(), Font.BOLD, getFontSize()));
        g2.setColor(Color.black);
        
        
        //left
        for(int i=0;i<leftMax && i<leftCount;i++)
        {
            if(dataA[leftSortedIndex[i]] == 1)
                break;
			
            if(focusKeywords[leftSortedIndex[i]] == true)
                g2.setColor(Color.red);
            else
                g2.setColor(Color.black);
            
            displayString = text.keyword[leftSortedIndex[i]].word +
                "("+dataA[leftSortedIndex[i]]+","+dataB[leftSortedIndex[i]]+ ")";
//            g2.drawString(displayString, sizeX * 5/100 + sizeX * 14/100 * (i%2), sizeY * 8/100 + sizeY * 3/100 * (int)(i/2) );
            g2.drawString(displayString, sizeX * 5/100, sizeY * 8/100 + sizeY * 3/100 * (i%30) );
        }
        
        //right
        for(int i=0;i<rightMax && i<rightCount;i++)
        {
            if(dataB[rightSortedIndex[i]] == 1)
                break;
            
            if(focusKeywords[rightSortedIndex[i]] == true)
                g2.setColor(Color.red);
            else
                g2.setColor(Color.black);
            
            displayString = text.keyword[rightSortedIndex[i]].word +
                "("+dataA[rightSortedIndex[i]]+","+dataB[rightSortedIndex[i]]+ ")";
//            g2.drawString(displayString, sizeX * 68/100 + sizeX * 14/100 * (i%2), sizeY * 8/100 + sizeY * 3/100 * (int)(i/2) );
            g2.drawString(displayString, sizeX * 68/100, sizeY * 8/100 + sizeY * 3/100 * (i%30) );
        }
        
        //center
        for(int i=0;i<centerMax && i<centerCount;i++)
        {
            if(dataA[centerSortedIndex[i]] == 0 || dataB[centerSortedIndex[i]] == 0)
                break;

            if(focusKeywords[centerSortedIndex[i]] == true)
                g2.setColor(Color.red);
            else
                g2.setColor(Color.black);

            displayString = text.keyword[centerSortedIndex[i]].word +
                "("+dataA[centerSortedIndex[i]]+","+dataB[centerSortedIndex[i]]+ ")";
            g2.drawString(displayString, sizeX * 40/100, sizeY * 8/100 + sizeY * 3/100 * (i%30) );
        }
    }
    
    public void createChiSquareIndex()
    {
        double chiThreshold = 3.84146; // P = 0.050
        
        boolean checkKeywords[] = new boolean[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            checkKeywords[i] = false;
        
        
        chiSquare = new double[text.keywordNumber];
        sideA = new boolean[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
        {
            if(dataA[i] != 0 || dataB[i] != 0)
                chiSquare[i] = calculateChiSquare(i);   //create sideA[]
            else
                chiSquare[i] = 0;
        }
        
        int sortedIndex[] = Qsort.getSortedIndex(chiSquare);
        
        /*
        for(int i=0;i<text.keywordNumber;i++)
//            if(sideA[sortedIndex[i]])
                System.out.println((i+1)+":"+text.keyword[sortedIndex[i]].word + "("+dataA[sortedIndex[i]]+","+dataB[sortedIndex[i]]+")"+chiSquare[i] );
        */
        
        //LEFT
        leftCount = 0;
        for(int i=0;i<text.keywordNumber;i++)
            if(chiSquare[i] > chiThreshold)
                leftCount++;
        System.out.println("leftCount="+leftCount);

        leftSortValue = new int[leftCount];
        leftSortedIndex = new int[leftCount];
        
        for(int i=0;i<leftCount;i++)
        {
//            leftSortValue[i] = chiSquare[i];
            leftSortedIndex[i] = sortedIndex[i];
            checkKeywords[sortedIndex[i]] = true;
        }
        
        
        //RIGHT
        rightCount = 0;
        for(int i=text.keywordNumber-1;i>=0;i--)
            if(chiSquare[i] < -chiThreshold)
                rightCount++;
        System.out.println("rightCount="+rightCount);
        
        rightSortValue = new int[rightCount];
        rightSortedIndex = new int[rightCount];
        
        for(int i=0;i<rightCount;i++)//
        {
//            rightSortValue[i] = chiSquare[text.keywordNumber-1-i];
            rightSortedIndex[i] = sortedIndex[text.keywordNumber-1-i];
            checkKeywords[sortedIndex[text.keywordNumber-1-i]] = true;
        }
        
        
        //CENTER
        double sortValue[] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            if(chiSquare[i] < 0)
                chiSquare[i] *= -1;
        
        Qsort.quicksort(chiSquare, sortedIndex, text.keywordNumber);
    
        
//        for(int i=text.keywordNumber-1; i>=0; i--)
  //          System.out.println((i+1)+":"+text.keyword[sortedIndex[i]].word + "("+dataA[sortedIndex[i]]+","+dataB[sortedIndex[i]]+")"+chiSquare[i] );
        
        int count=0;
        centerCount = 0;
        for(int i=text.keywordNumber-1; i>=0 && centerCount < centerMax; i--,count++)
        {
            if(checkKeywords[sortedIndex[text.keywordNumber-1-i]] == true)
                continue;
            
            centerCount++;
        }
        
        centerSortValue = new int[centerCount];
        centerSortedIndex = new int[centerCount];
        
        centerCount=0;
        for(int i=0;i<count && centerCount < centerMax;i++)
        {
            if(checkKeywords[sortedIndex[text.keywordNumber-1-i]] == true)
                continue;
            
            //            centerSortValue[centerCount] = sortValue[text.keywordNumber-1-i];
            centerSortedIndex[centerCount] = sortedIndex[text.keywordNumber-1-i];
            checkKeywords[sortedIndex[text.keywordNumber-1-i]] = true;
            
            centerCount++;
        }

    }
    /*
    public void createIndex()
    {
		int sortValue[] = new int[text.keywordNumber];
		int sortedIndex[] = new int[text.keywordNumber];
		boolean checkKeywords[] = new boolean[text.keywordNumber];
		
		for(int i=0;i<text.keywordNumber;i++)
			checkKeywords[i] = false;
		
		
		//LEFT
        for(int i=0;i<text.keywordNumber;i++)
            sortValue[i] = dataA[i] - dataB[i];
		
        Qsort.initializeIndex(sortedIndex, text.keywordNumber);
        Qsort.quicksort(sortValue, sortedIndex, text.keywordNumber);
		
		for(leftCount=0;leftCount<leftMax;leftCount++)
		{
			if(sortValue[leftCount] <= 0)
				break;			
		}
		
        leftSortValue = new int[leftCount];
        leftSortedIndex = new int[leftCount];		
		
		for(int i=0;i<leftCount;i++)
		{
			leftSortValue[i] = sortValue[i];
			leftSortedIndex[i] = sortedIndex[i];
			checkKeywords[sortedIndex[i]] = true;
		}
		
		
		//RIGHT
        for(int i=0;i<text.keywordNumber;i++)
            sortValue[i] = dataB[i] - dataA[i];
		
        Qsort.initializeIndex(sortedIndex, text.keywordNumber);
        Qsort.quicksort(sortValue, sortedIndex, text.keywordNumber);
		
		for(rightCount=0;rightCount<rightMax;rightCount++)
		{
			if(sortValue[rightCount] <= 0)
				break;			
		}
		
        rightSortValue = new int[rightCount];
        rightSortedIndex = new int[rightCount];		
		
		for(int i=0;i<rightCount;i++)//
		{
			rightSortValue[i] = sortValue[i];
			rightSortedIndex[i] = sortedIndex[i];
			checkKeywords[sortedIndex[i]] = true;
		}		
		
		
		//CENTER
        for(int i=0;i<text.keywordNumber;i++)
            sortValue[i] = dataA[i] + dataB[i];
		
        Qsort.initializeIndex(sortedIndex, text.keywordNumber);
        Qsort.quicksort(sortValue, sortedIndex, text.keywordNumber);

		centerCount=0;
		int count;
		for(count=0; centerCount < centerMax && count < text.keywordNumber; count++)
		{
			if(sortValue[count] <= 0)
				break;
			
			if(checkKeywords[sortedIndex[count]] == true)
				continue;
			
			centerCount++;
		}
		
        centerSortValue = new int[centerCount];
        centerSortedIndex = new int[centerCount];		
		
		centerCount=0;
		for(int i=0;i<count;i++)
		{
			if(checkKeywords[sortedIndex[i]] == true)
				continue;
			
			centerSortValue[centerCount] = sortValue[i];
			centerSortedIndex[centerCount] = sortedIndex[i];
			checkKeywords[sortedIndex[i]] = true;
			
			centerCount++;
		}
    }
     */

}
