//
// Mining module for TETDM 
// WordExtraction Version 0.10 2018.2.9
// Copyright(C) 2012.2.9 Yoko Nishihara
// 
// This module extracts words written in a dictionary.
// You should read the README file.
//

package module.MiningModules.WordExtraction;

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

import java.io.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

import java.util.*;

public class WordExtraction extends MiningModule implements ActionListener
{
	String dictionary[];
    boolean highLightData[];
    
    double data[][];
	
    ShrinkPanelForText shrinkPanel;
    JPanel lowerPanel;

    JTextField textfield;
    String query = "";
    
    JComboBox osusumeCombo;

    
    int displayMode = 1; // 0:Sentence, 1:Segment
	

    
    class ShrinkPanelForText extends JPanel implements ActionListener, ChangeListener
    {
        MiningModule mining;
        
        JComboBox itemCombo;
        JSlider valueSlider;
        JLabel valueLabel;
        JComboBox ijouCombo;
        
        double rowData[][];
        double dataRangeMin[];
        double dataRangeMax[];
        
        int columnNumber;
        
        String[] koumoku = {"ITEM"};
        String[] ijou = {"+","-"};
        String japaneseWords[];
        
        ShrinkPanelForText(String columnNames[], MiningModule mining, boolean inJapanese, String absolutePath)
        {
            this.mining = mining;
            columnNumber = columnNames.length-1;
            
            japaneseWords = FILEIO.TextFileAllReadCodeArray(new File(absolutePath+"module"+File.separator +"MiningModules"+File.separator +"WordInformation"+File.separator +"ShrinkJapanese.txt"));
            
            setLayout(new GridLayout(1,4));
            setBackground(new Color(255, 255, 0));
            setOpaque(true);
            
            if(inJapanese)
                koumoku[0] = japaneseWords[0];
            
            itemCombo = new JComboBox(koumoku);
            itemCombo.setMaximumRowCount(10);
            itemCombo.addActionListener(this);
            add(itemCombo);
            
            for(int i=0;i<columnNames.length;i++)
                itemCombo.addItem(columnNames[i]);
            
            valueSlider = new JSlider(0, 100, 50);
            valueSlider.addChangeListener(this);
            add(valueSlider);
            
            valueLabel = new JLabel();
            valueLabel.setText("0");
            add(valueLabel);
            
            if(inJapanese)
            {
                ijou[0] = japaneseWords[1];
                ijou[1] = japaneseWords[2];
            }
            
            ijouCombo = new JComboBox(ijou);
            ijouCombo.addActionListener(this);
            add(ijouCombo);
        }
        
        public void initializeData(double data[][])
        {
            boolean noData = false;
            
            rowData = new double[columnNumber][];
            dataRangeMin = new double[columnNumber];
            dataRangeMax = new double[columnNumber];
            
            for(int i=0;i<columnNumber;i++)
            {
                rowData[i] = new double[data[i].length];
                for(int j=0;j<data[i].length;j++)
                    rowData[i][j] = data[i][j];
                if(data[i].length == 0)
                    noData = true;
            }
            
            if(noData)
                return;
            
            calculateMaxMin();
        }
        
        void calculateMaxMin()
        {
            for(int i=0;i<columnNumber;i++)
            {
                dataRangeMax[i] = findMax(rowData[i]);
                dataRangeMin[i] = findMin(rowData[i]);
            }
        }
        
        double findMax(double a[])
        {
            double max = a[0];
            for(int i=1;i<a.length;i++)
                if(a[i] > max)
                    max = a[i];
            return max;
        }
        
        double findMin(double a[])
        {
            double min = a[0];
            for(int i=1;i<a.length;i++)
                if(a[i] < min)
                    min = a[i];
            return min;
        }
        
        int countData(double a[], double border, int ijou, boolean id[])
        {
            int count = 0;
            
            if(ijou == 0)
            {
                for(int i=0;i<a.length;i++)
                    if(a[i] >= border)
                    {
                        id[i] = true;
                        count++;
                    }
                    else
                        id[i] = false;
            }
            else
            {
                for(int i=0;i<a.length;i++)
                    if(a[i] <= border)
                    {
                        id[i] = true;
                        count++;
                    }
                    else
                        id[i] = false;
            }
            return count;
        }
        
        int countDataRange(double a[], double lower, double upper, boolean id[])
        {
            int count = 0;

            for(int i=0;i<a.length;i++)
                if(a[i] >= lower && a[i] <= upper)
                {
                    id[i] = true;
                    count++;
                }
                else
                    id[i] = false;

            return count;
        }
        

        
        public void createHighLight()
        {
            int selected = itemCombo.getSelectedIndex() - 1;
            int ijou = ijouCombo.getSelectedIndex();
            
            if(selected == -1)
            {
                displayMode = 1;
                miningOperations(0);
                displayOperations(0);
                return;
            }
            if(selected == 8)
            {
                displayMode = 0;
                miningOperations(0);
                displayOperations(0);
                return;
            }
            
            double max = dataRangeMax[selected];
            double min = dataRangeMin[selected];
            int border = (int)(min + (max-min)*valueSlider.getValue()/100.0);
            
            valueLabel.setText(" "+border);
            
            boolean id[];
            int count;
            
            switch(selected)
            {

                    //Segment extraction by conditional words inclusion
                case 0:        //0: frequency for segment//1: subject frequency for segment//2: segment frequency
                case 1:
                case 2:
                    id = new boolean[text.keywordNumber];
                    count = countData(rowData[selected], border, ijou, id);
                    dictionary = new String[count];
                    count = 0;
                    for(int i=0;i<text.keywordNumber;i++)
                        if(id[i])
                            dictionary[count++] = text.keyword[i].word;
                    
                    highLightData = new boolean[text.segmentNumber];//DUMMY FOR SEGMENT
                    setDataBooleanArray(0,highLightData);//DUMMY FOR SEGMENT
                    
                    miningOperations(23);
                    
                    displayMode = 1;    //SEGMENT
                    break;
                    
                    
                                //Segment extraction by value
                case 3:        //3: segment Length
                    highLightData = new boolean[text.segmentNumber];
                    count = countData(rowData[3], border, ijou, highLightData);
                    miningOperations(12);
                    
                    displayMode = 1;    //SEGMENT
                    break;
                    
                case 4:        //4: frequency for sentence//5: subject frequency for sentence//6: sentence frequency
                case 5:
                case 6:
                    id = new boolean[text.keywordNumber];
                    count = countData(rowData[selected], border, ijou, id);
                    dictionary = new String[count];
                    count = 0;
                    for(int i=0;i<text.keywordNumber;i++)
                        if(id[i])
                            dictionary[count++] = text.keyword[i].word;
                    
                    highLightData = new boolean[text.sentenceNumber];//DUMMY FOR SENTENCE
                    setDataBooleanArray(0,highLightData);//DUMMY FOR SENTENCE
                    
                    miningOperations(23);
                    
                    displayMode = 0;    //SENTENCE
                    break;
                    
                case 7:        //7: segntence Length
                    highLightData = new boolean[text.sentenceNumber];
                    count = countData(rowData[7], border, ijou, highLightData);
                    miningOperations(12);
                    
                    displayMode = 0;    //SENTENCE
                    break;
            }
        }
        
        public void stateChanged(ChangeEvent e)
        {
            createHighLight();
        }
        
        //Action listener
        public void actionPerformed(ActionEvent e)
        {
            mining.writeButtonLog(e);
            
            if(e.getSource() == ijouCombo)
                createHighLight();
            
            if(e.getSource() == itemCombo)
                createHighLight();
        }
    }


	public WordExtraction()
	{
		setModuleID(3);						// Set your module ID after you have got it
		setCategoryID(2);		
		pairingVisualizationID = new int[]{2};
//        displayOperationPanel = new boolean[]{true,false};
	}

	public void initializePanel()
	{
        lowerPanel = new JPanel();
        lowerPanel.setLayout(new GridLayout(1,4));
        lowerPanel.setBackground(new Color(255, 192, 203));
        lowerPanel.setOpaque(true);
        
        operationPanel.setLayout(new GridLayout(2,1));


//        if(isMenuInJapanese())

        
        textfield = new JTextField(10);
        textfield.addActionListener(this);
        lowerPanel.add(textfield);
        
        
        String[] osusume = {inJapanese[20],
            inJapanese[21],
            inJapanese[22],
            inJapanese[23],
            inJapanese[24],
            inJapanese[25],
            inJapanese[26],
            inJapanese[27],
            inJapanese[28],
            inJapanese[29],
            inJapanese[30],
            inJapanese[31],
            inJapanese[32],
            inJapanese[33],
            inJapanese[34],
            inJapanese[35],
            inJapanese[36],
            inJapanese[37],
            inJapanese[38],
            inJapanese[39],
            inJapanese[40],
            inJapanese[41],
            inJapanese[42],
        };
        
        osusumeCombo = new JComboBox(osusume);
        osusumeCombo.setMaximumRowCount(30);
        osusumeCombo.addActionListener(this);
        lowerPanel.add(osusumeCombo);

        ///////DATA SHRINK///////
        
        String columnNames[] = new String[9];
        for(int i=0;i<9;i++)
            columnNames[i] = inJapanese[10+i];
        
        shrinkPanel = new ShrinkPanelForText(columnNames, this, isMenuInJapanese(), text.control.absolutePath);
        operationPanel.add(shrinkPanel);
        
        operationPanel.add(lowerPanel);

	}
    
    void dataPreparation()
    {
        data = new double[8][];
        
        //0: frequency for Segment
        data[0] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            data[0][i] = text.keyword[i].frequency;
        
        //1: subject frequency for Segment
        data[1] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            data[1][i] = text.keyword[i].frequencyAsSubject;
        
        //2: document frequency
        data[2] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            data[2][i] = text.keyword[i].segmentFrequency;
        
        //3: segment Length
        data[3] = new double[text.segmentNumber];
        for(int i=0;i<text.segmentNumber;i++)
            data[3][i] = text.segment[i].segmentText.length();
        
        //4: frequency for Sentence
        data[4] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            data[4][i] = text.keyword[i].frequency;
        
        //5: subject frequency for Sentence
        data[5] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            data[5][i] = text.keyword[i].frequencyAsSubject;
        
        //6: document frequency
        data[6] = new double[text.keywordNumber];
        for(int i=0;i<text.keywordNumber;i++)
            data[6][i] = text.keyword[i].sentenceFrequency;
        
        //7: sentence Length
        data[7] = new double[text.sentenceNumber];
        for(int i=0;i<text.sentenceNumber;i++)
            data[7][i] = text.sentence[i].sentenceText.length();
    }

    public void initializeData()
    {
        dataPreparation();
        shrinkPanel.initializeData(data);
    }
	
    public void miningOperations(int optionNumber)
	{
	    switch(optionNumber)
		{
			case 0:
                if(displayMode == 0)
                    highLightData = new boolean[text.sentenceNumber];
                else if(displayMode == 1)
                    highLightData = new boolean[text.segmentNumber];
                setDataBooleanArray(0,highLightData);//DUMMY FOR SENTENCE
                break;
                
            case 23:
                setDataInteger(2,13);
                setDataStringArray(0,dictionary);
                displayOperations(35);
                break;
                
            case 12:
                setDataBooleanArray(0,highLightData);
                displayOperations(36);
                break;
                
            case 25:
                setDataInteger(2,13);
                setDataStringArray(0,textfield.getText().split(" "));
                displayOperations(35);
                break;
		}
	}
	
/*
    
	String createDictionaryWords()
	{
		StringWriter sw = new StringWriter();			//For words
		BufferedWriter bw = new BufferedWriter(sw);	
		
		try{
			for(int i=0; i<dictionary.length; i++)
			{
				bw.write(dictionary[i]);
				bw.newLine();				
			}
			bw.flush();
		}
		catch(Exception e){
			System.out.println("writing ERROR in WordExtraction");
		}		
		
		return sw.toString();		
	}
*/

	//Action listener
	public void actionPerformed(ActionEvent e)
	{
		writeButtonLog(e);
//		insideOfActionPerformed(e);

		if(e.getSource () == textfield)
			miningOperations(25);
		
        if(e.getSource () == osusumeCombo)
            easyHighLight();
    }


    

    
    //osusume
    public void easyHighLight()
    {
        int optionNumber = osusumeCombo.getSelectedIndex() - 1;
        
        if(optionNumber == -1)
            return;
        
        boolean id[];
        int count;
        
        switch(optionNumber)
        {
            case 0: // 0:frequency 1  // 1:subject frequency 1  //2:segment frequency 1
            case 1:
            case 2:
                id = new boolean[text.keywordNumber];

                if(optionNumber == 2)
                    count = shrinkPanel.countDataRange(shrinkPanel.rowData[optionNumber], 0.9, 1.1, id);
                else
                    count = shrinkPanel.countData(shrinkPanel.rowData[optionNumber], 1.1, 1, id);
                
                dictionary = new String[count];
                count = 0;
                for(int i=0;i<text.keywordNumber;i++)
                    if(id[i])
                        dictionary[count++] = text.keyword[i].word;
                
                highLightData = new boolean[text.segmentNumber];//DUMMY FOR SEGMENT
                setDataBooleanArray(0,highLightData);//DUMMY FOR SEGMENT
                
                miningOperations(23);
                
                displayMode = 1;    //SEGMENT
                break;
                
            case 3:
            case 4:
            case 5:
                id = new boolean[text.keywordNumber];
                
                count = shrinkPanel.countData(shrinkPanel.rowData[optionNumber-3], shrinkPanel.dataRangeMax[optionNumber-3], 0, id);
                
                dictionary = new String[count];
                count = 0;
                for(int i=0;i<text.keywordNumber;i++)
                    if(id[i])
                        dictionary[count++] = text.keyword[i].word;
                
                highLightData = new boolean[text.segmentNumber];//DUMMY FOR SEGMENT
                setDataBooleanArray(0,highLightData);//DUMMY FOR SEGMENT
                
                miningOperations(23);
                
                displayMode = 1;    //SEGMENT
                break;
                
            case 6:
            case 7:
            case 8:
                id = new boolean[text.keywordNumber];
                
                count = shrinkPanel.countData(shrinkPanel.rowData[optionNumber-6], 1.9, 0, id);
                
                dictionary = new String[count];
                count = 0;
                for(int i=0;i<text.keywordNumber;i++)
                    if(id[i])
                        dictionary[count++] = text.keyword[i].word;
                
                highLightData = new boolean[text.segmentNumber];//DUMMY FOR SEGMENT
                setDataBooleanArray(0,highLightData);//DUMMY FOR SEGMENT
                
                miningOperations(23);
                
                displayMode = 1;    //SEGMENT
                break;
                
            case 9:
                highLightData = new boolean[text.segmentNumber];
                count = shrinkPanel.countData(shrinkPanel.rowData[3], 100, 0, highLightData);
                miningOperations(12);
                
                displayMode = 1;    //SEGMENT
                break;
                
            case 10:
                highLightData = new boolean[text.segmentNumber];
                count = shrinkPanel.countData(shrinkPanel.rowData[3], 99, 1, highLightData);
                miningOperations(12);
                
                displayMode = 1;    //SEGMENT
                break;
                
            case 11: // 0:frequency 1  // 1:subject frequency 1  //2:segment frequency 1
            case 12:
            case 13:
                id = new boolean[text.keywordNumber];
                
                if(optionNumber == 12)
                    count = shrinkPanel.countDataRange(shrinkPanel.rowData[optionNumber-7], 0.9, 1.1, id);
                else
                    count = shrinkPanel.countData(shrinkPanel.rowData[optionNumber-7], 1.1, 1, id);
                
                
                dictionary = new String[count];
                count = 0;
                for(int i=0;i<text.keywordNumber;i++)
                    if(id[i])
                        dictionary[count++] = text.keyword[i].word;
                
                highLightData = new boolean[text.sentenceNumber];//DUMMY FOR SENTENCE
                setDataBooleanArray(0,highLightData);//DUMMY FOR SENTENCE
                
                miningOperations(23);
                
                displayMode = 0;    //SENTENCE
                break;
                
            case 14:
            case 15:
            case 16:
                id = new boolean[text.keywordNumber];
                
                count = shrinkPanel.countData(shrinkPanel.rowData[optionNumber-10], shrinkPanel.dataRangeMax[optionNumber-10], 0, id);
                
                dictionary = new String[count];
                count = 0;
                for(int i=0;i<text.keywordNumber;i++)
                    if(id[i])
                        dictionary[count++] = text.keyword[i].word;
                
                highLightData = new boolean[text.sentenceNumber];//DUMMY FOR SENTENCE
                setDataBooleanArray(0,highLightData);//DUMMY FOR SENTENCE
                
                miningOperations(23);
                
                displayMode = 0;    //SENTENCE
                break;
                
            case 17:
            case 18:
            case 19:
                id = new boolean[text.keywordNumber];
                
                count = shrinkPanel.countData(shrinkPanel.rowData[optionNumber-13], 1.9, 0, id);
                
                dictionary = new String[count];
                count = 0;
                for(int i=0;i<text.keywordNumber;i++)
                    if(id[i])
                        dictionary[count++] = text.keyword[i].word;
                
                highLightData = new boolean[text.sentenceNumber];//DUMMY FOR SENTENCE
                setDataBooleanArray(0,highLightData);//DUMMY FOR SENTENCE
                
                miningOperations(23);
                
                displayMode = 0;    //SENTENCE
                break;
                
            case 20:
                highLightData = new boolean[text.sentenceNumber];
                count = shrinkPanel.countData(shrinkPanel.rowData[7], 100, 0, highLightData);
                miningOperations(12);
                
                displayMode = 0;    //SENTENCE
                break;
                
            case 21:
                highLightData = new boolean[text.sentenceNumber];
                count = shrinkPanel.countData(shrinkPanel.rowData[7], 99, 1, highLightData);
                miningOperations(12);
                
                displayMode = 0;    //SENTENCE
                break;
                

                
        }

    }
    
    
}
