//
// Visuzalization module for TETDM 
// TextDisplaySelect Version 4.00
// Copyright(C) 2018- WATARU SUNAYAMA ALL RIGHTS RESERVED.
//
// This program is provided under the licenses.
// You Should read the README file.
//



package module.VisualizationModules.TextDisplaySelect;

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.*;
import javax.swing.text.*;

import java.util.regex.*;

import javax.swing.plaf.ComponentUI;

public class TextDisplaySelect extends VisualizationModule
{
	//Text pane
//	JTextPane text1;
    NonWrappingTextPane text1;
	JScrollPane scroll1;	



	//for text DISPLAY
	StyleContext sc;
  	DefaultStyledDocument doc;
	MutableAttributeSet attr[];

    boolean selectedData[];
    int sentLength[];

	int fontsize;
    
    //for label
    
    int conditionNumber;
    String conditionIcon[];
    boolean condition[][];
    int labelAttribute[];
    
    boolean segmentMode;
    boolean sentenceMode;
    
    boolean andCondition;
    
    boolean selectedCondition[];
    int endPosition;
    
	public TextDisplaySelect()
	{
		setModuleID(26);
		setCategoryID(1);
		setUseMode(0);
        dataNumbers = new int[]{1,0,0,0,    // b,i,d,S
            0,1,0,1,    // bA,iA,dA,SA
            1,0,0};     // bA2,iA2,dA2
		setToolType(3);
	}
    
    
    public class NonWrappingTextPane extends JTextPane
    {
        public NonWrappingTextPane() {
            super();
        }
        
        public NonWrappingTextPane(StyledDocument doc) {
            super(doc);
        }
        
        // Override getScrollableTracksViewportWidth
        // to preserve the full width of the text
        /*
        public boolean getScrollableTracksViewportWidth()
        {
            Component parent = getParent();
            ComponentUI ui = getUI();
            
            return parent != null ? (ui.getPreferredSize(this).width <= parent.getSize().width) : true;
        }
         */
        public boolean getScrollableTracksViewportWidth()
        {
            return false;
        }
    }
    

	public void initializePanel()
	{
//        text1 = new JTextPane();
        text1 = new NonWrappingTextPane();
        text1.addMouseListener(this);
        
		scroll1 = new JScrollPane(text1);
		add(scroll1);
		
		scroll1.addMouseWheelListener(this);
		scroll1.getVerticalScrollBar().addAdjustmentListener(this);			

		colorSettings();
	}		
	
	public void initializeData()
	{
		fontsize = 14;
		
        conditionNumber = 0;
        segmentMode = false;
        sentenceMode = false;
        andCondition = false;
        
        selectedData = new boolean[text.segmentNumber];
        sentLength = new int[text.segmentNumber];
        endPosition = 0;
	}
	
	public void setFont()
	{
		fontsize = getFontSize();
	}	

	public void displayOperations(int optionNumber)
	{
		switch(optionNumber)
		{
            case 0:
                if(segmentMode)
                {
                    if(countSelectedCondition() == 0)
                        makeDocumentBySegments();
                    else
                        makeDocumentBySegments(selectedCondition);
                }
                else if(sentenceMode)
                {
                    if(countSelectedCondition() == 0)
                        makeDocumentBySentences();
                    else
                        makeDocumentBySentences(selectedCondition);
                }
                else
                    makeDocument();

                text1.setFont(new Font(text.getFontName(), Font.BOLD, fontsize));
                text1.setDocument(doc);
                text1.setCaretPosition(0);
                break;
                
            case 37:   //KEEP CARET POSITION
                if(segmentMode)
                {
                    if(countSelectedCondition() == 0)
                        makeDocumentBySegments();
                    else
                        makeDocumentBySegments(selectedCondition);
                }
                else if(sentenceMode)
                {
                    if(countSelectedCondition() == 0)
                        makeDocumentBySentences();
                    else
                        makeDocumentBySentences(selectedCondition);
                }
                else
                    makeDocument();
                
                text1.setFont(new Font(text.getFontName(), Font.BOLD, fontsize));
                text1.setDocument(doc);
                text1.setCaretPosition(endPosition);
                break;

			case 9:
				fontsize--;
				displayOperations(0);
				break;
				
			case 10:
				fontsize++;
				displayOperations(0);
				break;
		}		
	}

    int countSelectedCondition()
    {
        if(selectedCondition == null)
            return 0;
        
        int count = 0;
        
        for(int i=0;i<conditionNumber;i++)
            if(selectedCondition[i] == true)
                count++;
        
        return count;
    }


	
	void colorSettings()
	{
		attr = new SimpleAttributeSet[23];
		for(int i=0;i<attr.length;i++)
			attr[i] = new SimpleAttributeSet();

		Color cl[] = new Color[attr.length];
		cl[0] = new Color(255, 255, 255);
		cl[1] = new Color(255, 255, 55);//4.0
		cl[2] = new Color(220, 220, 0);//3.5
		cl[3] = new Color(220, 220, 0);//3.0
		cl[4] = new Color(190, 190, 0);//2.5
		cl[5] = new Color(190, 190, 0);//2.0
		cl[6] = new Color(120, 120, 0);//1.5
		cl[7] = new Color(120, 120, 0);//1.0
		cl[8] = new Color(100, 100, 0);//0.5
		cl[9] = new Color(50, 50, 0);	//0
		cl[10] = new Color(255, 255, 255);//white
		cl[11] = new Color(0,0,0);		//black
        
        //12 - 31 (0-19)
        cl[12] = new Color(255, 255, 0);//yellow
        cl[13] = new Color(0, 255, 0);//green
        cl[14] = new Color(0,255,255);//cyan
        cl[15] = new Color(0xff,0xc0,0xcb);//pink
        
        cl[16] = new Color(0xee,0x82,0xee);//violet
        cl[17] = new Color(0xff,0xa5,0x00);//orange
        cl[18] = new Color(0x7f,0xff,0xd4);//aquamarine

        cl[19] = new Color(0xff,0xd7,0x00);//gold
        cl[20] = new Color(0xff,0x7f,0x50);//coral
        cl[21] = new Color(0xee,0xe8,0xaa);//palegoldenrod

        cl[22] = new Color(255, 255, 255);//white



		for(int i=0;i<attr.length;i++)
			StyleConstants.setBackground(attr[i], cl[i]);
        
        StyleConstants.setForeground(attr[22], cl[10]); // NO DISPLAY
		
		sc = new StyleContext();
	}
    
    public boolean setData(int dataID, String data[])   //condition icon
    {
        switch(dataID)
        {
            case 0:
                conditionNumber = data.length;
                
                conditionIcon = new String[conditionNumber];
                for(int i=0;i<conditionNumber;i++)
                    conditionIcon[i] = data[i];
                return true;
        }
        return false;
    }
    
    public boolean setData(int dataID, int data[])   //condition attribute
    {
        switch(dataID)
        {
            case 0:
                if(data.length == 0 || data.length != conditionNumber)
                    return false;
                
                labelAttribute = new int[conditionNumber];
                for(int i=0;i<conditionNumber;i++)
                    labelAttribute[i] = data[i];
                return true;
        }
        return false;
    }
    
    public boolean setData(int dataID, boolean data[][])   //condition matching
    {
        switch(dataID)
        {
            case 0:
                if(conditionNumber == 0)
                    return false;
                
                int dataNumber = data[0].length;
                if(dataNumber == text.segmentNumber)
                {
                    segmentMode = true;
                    sentenceMode = false;
                    selectedData = new boolean[text.segmentNumber];
                    sentLength = new int[text.segmentNumber];
                }
                else if(dataNumber == text.sentenceNumber)
                {
                    segmentMode = false;
                    sentenceMode = true;
                    selectedData = new boolean[text.sentenceNumber];
                    sentLength = new int[text.sentenceNumber];
                }
                else
                {
                    segmentMode = false;
                    sentenceMode = false;
                    selectedData = new boolean[text.segmentNumber];
                    sentLength = new int[text.segmentNumber];
                    return false;
                }
                
                condition = new boolean[conditionNumber][dataNumber];

                for(int i=0;i<conditionNumber;i++)
                    for(int j=0;j<dataNumber;j++)
                        condition[i][j] = data[i][j];

                return true;
        }
        return false;
    }
    
    public boolean setData(int dataID, boolean data[])  //selected condition
    {
        switch(dataID)
        {
            case 0:
                if(data.length == 0 || data.length != conditionNumber)
                    return false;
                
                selectedCondition = new boolean[conditionNumber];
                for(int i=0;i<conditionNumber;i++)
                    selectedCondition[i] = data[i];
                return true;
        }
        return false;
    }
    
    public boolean setData(int dataID, boolean data)
    {
        switch(dataID)
        {
            case 0:
                andCondition = data;
                return true;
        }
        return false;
    }

    void makeDocument()
    {
        doc = new DefaultStyledDocument(sc);
        int offset = 0;
        
        try{
            String sent;
            for(int i=0;i<text.segmentNumber;i++)
            {
                sent = "["+(text.segment[i].segmentID+1)+"]"+text.segment[i].segmentText.replaceAll(System.getProperty("line.separator"),"")+System.getProperty("line.separator");
                sentLength[i] = sent.length();
                
                if(selectedData[i])
                    doc.insertString(offset, sent, attr[1]);
                else
                    doc.insertString(offset, sent, attr[10]);
                offset += sent.length();
            }
        }
        catch (BadLocationException ble){
            System.err.println("Accessed at illegal position out of the document.");
        }
    }
    
    void makeDocumentBySegments(boolean useCondition[])
    {
        attentionSegments = text.attention.getAttentionSegments();
        
        doc = new DefaultStyledDocument(sc);
        int offset = 0;
        
        try{
            String sent;
            for(int i=0;i<text.segmentNumber;i++)
            {
                sentLength[i] = 0;
                if(andCondition == false)
                {
                    int k;
                    for(k=0;k<conditionNumber;k++)
                        if(condition[k][i] && useCondition[k])
                            break;
                    if(k == conditionNumber)
                        continue;
                }
                else
                {
                    int count1=0, count2=0;
                    for(int k=0;k<conditionNumber;k++)
                        if(useCondition[k])
                        {
                            count1++;
                            if(condition[k][i])
                                count2++;
                        }

                    if(count1 == 0 || count1 != count2)
                        continue;
                }
                
                for(int j=0;j<conditionNumber;j++)
                {
                    sent = conditionIcon[j];
                    if(condition[j][i])
                    {
                        if(labelAttribute == null)
                            doc.insertString(offset, sent, attr[j%10+12]);
                        else
                            doc.insertString(offset, sent, attr[labelAttribute[j]]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                    }
                    else
                    {
                        doc.insertString(offset, sent, attr[22]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                        /*
                        doc.insertString(offset, inJapanese[0], attr[10]);
                        offset += inJapanese[0].length();
                        sentLength[i] += inJapanese[0].length();
                         */
                    }
                }
                
                //                sent = System.getProperty("line.separator");
                //              doc.insertString(offset, sent, attr[1]);
                //            offset += sent.length();
                
                
                sent = "["+(text.segment[i].segmentID+1)+"]"+text.segment[i].segmentText.replaceAll(System.getProperty("line.separator"),"")+System.getProperty("line.separator");
                sentLength[i] += sent.length();

                if(attentionSegments[i])
                    doc.insertString(offset, sent, attr[13]);
                else if(selectedData[i])
                    doc.insertString(offset, sent, attr[1]);
                else
                    doc.insertString(offset, sent, attr[10]);
                
                offset += sent.length();
            }
        }
        catch (BadLocationException ble){
            System.err.println("Accessed at illegal position out of the document.");
        }
    }
    
    void makeDocumentBySegments()
    {
        attentionSegments = text.attention.getAttentionSegments();
        
        doc = new DefaultStyledDocument(sc);
        int offset = 0;

        try{
            String sent;
            for(int i=0;i<text.segmentNumber;i++)
            {
                sentLength[i] = 0;
                for(int j=0;j<conditionNumber;j++)
                {
                    sent = conditionIcon[j];
                    if(condition[j][i])
                    {
                        if(labelAttribute == null)
                            doc.insertString(offset, sent, attr[j%10+12]);
                        else
                            doc.insertString(offset, sent, attr[labelAttribute[j]]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                    }
                    else
                    {
                        doc.insertString(offset, sent, attr[22]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                        /*
                        doc.insertString(offset, inJapanese[0], attr[10]);
                        offset += inJapanese[0].length();
                        sentLength[i] += inJapanese[0].length();
                         */
                    }
                }
                
                //                sent = System.getProperty("line.separator");
                //              doc.insertString(offset, sent, attr[1]);
                //            offset += sent.length();
                
                
                sent = "["+(text.segment[i].segmentID+1)+"]"+text.segment[i].segmentText.replaceAll(System.getProperty("line.separator"),"")+System.getProperty("line.separator");
                sentLength[i] += sent.length();
                
                if(attentionSegments[i])
                    doc.insertString(offset, sent, attr[13]);
                else if(selectedData[i])
                    doc.insertString(offset, sent, attr[1]);
                else
                    doc.insertString(offset, sent, attr[10]);
                
                offset += sent.length();
            }
        }
        catch (BadLocationException ble){
            System.err.println("Accessed at illegal position out of the document.");
        }
    }

    void makeDocumentBySentences(boolean useCondition[])
    {
        attentionSentences = text.attention.getAttentionSentences();
        
        doc = new DefaultStyledDocument(sc);
        int offset = 0;
        
        try{
            String sent;
            for(int i=0;i<text.sentenceNumber;i++)
            {
                sentLength[i] = 0;
                if(andCondition == false)
                {
                    int k;
                    for(k=0;k<conditionNumber;k++)
                        if(condition[k][i] && useCondition[k])
                            break;
                    if(k == conditionNumber)
                        continue;
                }
                else
                {
                    int count1=0, count2=0;
                    for(int k=0;k<conditionNumber;k++)
                        if(useCondition[k])
                        {
                            count1++;
                            if(condition[k][i])
                                count2++;
                        }
                    
                    if(count1 == 0 || count1 != count2)
                        continue;
                }
                
                for(int j=0;j<conditionNumber;j++)
                {
                    sent = conditionIcon[j];
                    if(condition[j][i])
                    {
                        if(labelAttribute == null)
                            doc.insertString(offset, sent, attr[j%10+12]);
                        else
                            doc.insertString(offset, sent, attr[labelAttribute[j]]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                    }
                    else
                    {
                        doc.insertString(offset, sent, attr[22]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                        /*
                        doc.insertString(offset, inJapanese[0], attr[10]);
                        offset += inJapanese[0].length();
                        sentLength[i] += inJapanese[0].length();
                         */
                    }
                }
                

                
                //                sent = System.getProperty("line.separator");
                //              doc.insertString(offset, sent, attr[1]);
                //            offset += sent.length();
                
                
                sent = "("+(text.sentence[i].sentenceID+1)+")"+text.sentence[i].sentenceText.replaceAll(System.getProperty("line.separator"),"")+System.getProperty("line.separator");
                sentLength[i] += sent.length();
                
                if(attentionSentences[i])
                    doc.insertString(offset, sent, attr[13]);
                else if(selectedData[i])
                    doc.insertString(offset, sent, attr[1]);
                else
                    doc.insertString(offset, sent, attr[10]);
                
                offset += sent.length();
            }
        }
        catch (BadLocationException ble){
            System.err.println("Accessed at illegal position out of the document.");
        }
    }
    
    void makeDocumentBySentences()
    {
        attentionSentences = text.attention.getAttentionSentences();
        
        doc = new DefaultStyledDocument(sc);
        int offset = 0;
        
        try{
            String sent;
            for(int i=0;i<text.sentenceNumber;i++)
            {
                sentLength[i] = 0;
                for(int j=0;j<conditionNumber;j++)
                {
                    sent = conditionIcon[j];
                    if(condition[j][i])
                    {
                        if(labelAttribute == null)
                            doc.insertString(offset, sent, attr[j%10+12]);
                        else
                            doc.insertString(offset, sent, attr[labelAttribute[j]]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                    }
                    else
                    {
                        doc.insertString(offset, sent, attr[22]);
                        offset += sent.length();
                        sentLength[i] += sent.length();
                        /*
                        doc.insertString(offset, inJapanese[0], attr[10]);
                        offset += inJapanese[0].length();
                        sentLength[i] += inJapanese[0].length();
                         */
                    }
                }
                
//                sent = System.getProperty("line.separator");
  //              doc.insertString(offset, sent, attr[1]);
    //            offset += sent.length();
                
                
                sent = "("+(text.sentence[i].sentenceID+1)+")"+text.sentence[i].sentenceText.replaceAll(System.getProperty("line.separator"),"")+System.getProperty("line.separator");
                sentLength[i] += sent.length();
                
                if(attentionSentences[i])
                    doc.insertString(offset, sent, attr[13]);
                else if(selectedData[i])
                    doc.insertString(offset, sent, attr[1]);
                else
                    doc.insertString(offset, sent, attr[10]);
                
                offset += sent.length();
            }
        }
        catch (BadLocationException ble){
            System.err.println("Accessed at illegal position out of the document.");
        }
    }

    public int countLine(int position)
    {
        int total = 0;
        for(int i=0;i<selectedData.length;i++)
        {
            total += sentLength[i];
            if(position < total)
                return i;
        }
        return -1;
    }

    //Mouse Event
    public void mouseClicked(MouseEvent e)
    {
        writeClickLog();
        
        if(segmentMode || sentenceMode)
        {
            for(int i=0;i<selectedData.length;i++)
                selectedData[i] = false;
            
            endPosition = text1.getCaretPosition();
            int focusLine = countLine(endPosition);
            
            if(focusLine != -1)
            {
                if(segmentMode)
                {
                    setMainFocusSegment(focusLine,true);
                }
                if(sentenceMode)
                {
                    setMainFocusSentence(focusLine,true);
                }
                selectedData[focusLine] = true;
            }
            else
                resetMainSub();
            repaintOthersByFocus();
            executeOthersByFocus();
            displayOperations(37);
        }
    }
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}

}
