//
// Core Program for TETDM 
// ACTIONLOG.java Version 1.00
// Copyright(C) 2017-2018 TETDM CORE MEMBER ALL RIGHTS RESERVED.
// This program is provided under the license.
//


package source;

import java.io.*;
import java.text.*;
import java.awt.*;

import javax.swing.JFrame;

public class ACTIONLOG
{
    static String historyDirectory;
    static String logDirectory;
    static String logFilename;
    static File logFile;
    static boolean createNewActionLog = true;
    
    static long startTime=0, endTime;
    static long logStartTime=0;
    static String timeInformation;
    
    static String conservedOperationStartLog="";
    static String conservedOperationEndLog="";
    static int logCounter=0;
    static int lastMoveCount = -99;
    static int lastDragCount = -99;
    static int lastWheelCount = -99;
    static int lastDragBarCount = -99;
    static int adjustedX=-99, adjustedY=-99;
    
    static int logX, logY;
    
    static String newLine = System.getProperty("line.separator");

    static String version;
    static String pcSize;
    static String pcSpeed;
    
    //EXECUTE.largeFileCopy(filename1, filename2);
    
    /////////////////////
    static String logDirectoryName[];
    static int logDirectoryNameMaxNumber = 100;
    static int logDirectoryNameCount = 0;
    
    public static void initializeLogDirectoryNameList()
    {
        logDirectoryName = new String[logDirectoryNameMaxNumber];
        logDirectoryNameCount = 0;
    }
    
    public static void addDirectoryName()
    {
        if(logDirectoryNameCount < logDirectoryNameMaxNumber)
            logDirectoryName[logDirectoryNameCount++] = logDirectory;
        else
            System.out.println("logDirectoryNameCount reaches to the maximum : "+logDirectoryNameMaxNumber);
    }
    
    public static void deleteDirectoryName()
    {
        logDirectoryNameCount--;
    }
    
    public static String[] getLogDirectoryNameList()
    {
        String nameList[] = new String[logDirectoryNameCount];
        for(int i=0;i<logDirectoryNameCount;i++)
            nameList[i] = logDirectoryName[i];

        return nameList;
    }
    /////////////////////
    
    public static void setLogDirectory(String absolutePath)
    {
        historyDirectory = absolutePath + "imitateLog" + File.separator;
    }
    
    public static void createLogDirectory()
    {
        logDirectory = historyDirectory+logStartTime+File.separator;
        File newdir = new File(logDirectory);
        newdir.mkdir();
        addDirectoryName();
        logFilename = logDirectory + "NEWACTIONLOG";
        logFile = new File(logFilename);
        
        writeActionLog(version);
        writeActionLog(pcSize);
        writeActionLog(pcSpeed);
    }
    
    public static void deleteLogDirectory()
    {
        logFile.delete();
        
        File deleteDir = new File(logDirectory);
        deleteDir.delete();
        deleteDirectoryName();
    }
    
    public static void deleteDir(File file, int depth)
    {
        if (!file.exists())
            return;
        
        if (file.isDirectory())
            for (File child : file.listFiles())
                deleteDir(child, depth+1);

        if(depth != 0)
            file.delete();
    }
    
    public static void deleteAllLogFiles()
    {
        deleteDir(new File(historyDirectory), 0);
    }
    
    public static void setCreateLogFile(boolean setCreation)
    {
        createNewActionLog = setCreation;
    }
    
    public static void setStartTime()
    {
        startTime = endTime = logStartTime = System.nanoTime();
    }
    
    public static void setLogStartTime()
    {
        logStartTime = System.nanoTime();
    }
    
    public static double getDiffTime()
    {
        endTime = System.nanoTime();
        
        /*
         System.out.println("Start = "+startTime);
         System.out.println("End = "+endTime);
         System.out.println("DIFF = "+(endTime - startTime));
         */
        
        if(startTime == 0)
            return 0.0;
        else
//            return (double)(endTime - startTime)/1000000000.0;
            return (double)(endTime - logStartTime)/1000000000.0;
    }
    
    public static void setDiffTime()
    {
        timeInformation = String.format("%.2f",getDiffTime());
    }
    
    //delete log folder if the log does not have significance
    public static void checkLogFile()
    {
        double duration = (endTime - logStartTime)/1000000000.0;
        String durationInformation = String.format("%.2f",duration);
        
        if(duration < 10.0)
        {
            writeActionLog("----------DELETE LOG----------");
            deleteLogDirectory();
        }
        else
            writeActionLog("SYSTEM*PC*DURATION*"+durationInformation);
    }
    
    //time information and new line are automatically added.
    public static void writeActionLog(String logData)
    {
        if(createNewActionLog == false)
            return;

        setDiffTime();
        
        try
        {
            BufferedWriter bw1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFilename, true), "Shift_JIS"));
            
            if(!conservedOperationEndLog.equals(""))
            {
                bw1.write(conservedOperationStartLog+newLine);
                bw1.write(conservedOperationEndLog+newLine);
                conservedOperationStartLog = conservedOperationEndLog = "";
            }

            bw1.write(timeInformation+"*"+logData+newLine);
            bw1.close();
            
            logCounter++;
        }
        catch(FileNotFoundException e){
            System.out.println("Log File is not created until new tools are set.");
        }
        catch(Exception e){
            System.out.println("File Writing ERROR in creating NEWACTIONLOG, STRING");
        }
    }

    public static void writeConservedLog()
    {
        if(createNewActionLog == false)
            return;
        
        if(conservedOperationEndLog.equals(""))
            return;

        try
        {
            BufferedWriter bw1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFilename, true), "Shift_JIS"));
            
            bw1.write(conservedOperationStartLog+newLine);
            bw1.write(conservedOperationEndLog+newLine);
            conservedOperationStartLog = conservedOperationEndLog = "";

            bw1.close();
            
            logCounter++;
        }
        catch(FileNotFoundException e){
            System.out.println("Log File is not created until new tools are set.");
        }
        catch(Exception e){
            System.out.println("File Writing ERROR in creating NEWACTIONLOG, STRING");
        }
    }
    
    public static void getComponentXY(Component component)
    {
        Point S;
        try
        {
            S = component.getLocationOnScreen();
        }
        catch(Exception e){
            S = new Point(-999,-999);
        }
        
        Dimension QD = component.getSize();
        
        logX = S.x + QD.width/2;
        logY = S.y + QD.height/2;
    }
    
    //TEXT  //time information and new line are automatically added.
    public static void writeTextInputLog(String windowName, String inputText)
    {
        writeActionLog(windowName+"*KEYBOARD*TEXT*"+inputText);
    }
    
    //BUTTON
    public static void writeButtonLog(String windowName, String buttonName, Component component)
    {
        getComponentXY(component);
        writeActionLog(windowName+"*COMPONENT*BUTTON*"+logX+":"+logY+"*"+buttonName);
    }
    
    //MOUSE
    public static void writeMouseLog(String windowName, String operation)
    {
        PointerInfo ce = MouseInfo.getPointerInfo();
        Point pose = ce.getLocation();
        logX = (int)pose.getX();
        logY = (int)pose.getY();
        String mouseInformation = logX+":"+logY;
        
        setDiffTime();
        
        if(operation.equals("MOVE"))
        {
            if(lastMoveCount != logCounter)
            {
                writeConservedLog();
                logCounter++;
                
                conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-START*"+mouseInformation;
                lastMoveCount = logCounter;
            }
            else
                conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-END*"+mouseInformation;
            return;
        }
        
        if(operation.equals("DRAG"))
        {
            if(lastDragCount != logCounter)
            {
                writeConservedLog();
                logCounter++;
                
                conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-START*"+mouseInformation;
                lastDragCount = logCounter;
            }
            else
                conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-END*"+mouseInformation;
            return;
        }
        
        if(operation.equals("DRAG(BAR-ADJUSTED)"))
        {
            if(lastDragBarCount != logCounter)
            {
                writeConservedLog();
                logCounter++;
                
                conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-START*"+mouseInformation;
                lastDragBarCount = logCounter;
                adjustedX = logX;
                adjustedY = logY;
            }
            else
                if(logX != adjustedX || logY != adjustedY)
                    conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-END*"+mouseInformation;
            return;
        }
        
        writeActionLog(windowName+"*MOUSE*"+operation+"*"+mouseInformation);
    }

    
    //FROM MODULE
    //TEXT  //time information and new line are automatically added.
    public static void writeTextInputLogFromModule(String windowName, String inputText, int miningID, int visualizationID)
    {
        writeActionLog(windowName+"*KEYBOARD*TEXT*"+inputText+"*"+miningID+":"+visualizationID);
    }
    
    //BUTTON
    public static void writeButtonLogFromModule(String windowName, String buttonName, int miningID, int visualizationID, Component component)
    {
        getComponentXY(component);
        writeActionLog(windowName+"*COMPONENT*BUTTON*"+logX+":"+logY+"*"+miningID+":"+visualizationID+"*"+buttonName);
    }
    
    //MOUSE
    public static void writeMouseLogFromModule(String windowName, String operation, int miningID, int visualizationID)
    {
        PointerInfo ce = MouseInfo.getPointerInfo();
        Point pose = ce.getLocation();
        logX = (int)pose.getX();
        logY = (int)pose.getY();
        String mouseInformation = logX+":"+logY;
        
        setDiffTime();
        
        if(operation.equals("MOVE"))
        {
            if(lastMoveCount != logCounter)
            {
                writeConservedLog();
                logCounter++;
                
                conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-START*"+mouseInformation+"*"+miningID+":"+visualizationID;
                lastMoveCount = logCounter;
            }
            else
                conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-END*"+mouseInformation+"*"+miningID+":"+visualizationID;
            return;
        }
        
        if(operation.equals("DRAG"))
        {
            if(lastDragCount != logCounter)
            {
                writeConservedLog();
                logCounter++;
                
                conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-START*"+mouseInformation+"*"+miningID+":"+visualizationID;
                lastDragCount = logCounter;
            }
            else
                conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-END*"+mouseInformation+"*"+miningID+":"+visualizationID;
            return;
        }
        
        if(operation.equals("DRAG(BAR-ADJUSTED)"))
        {
            if(lastDragBarCount != logCounter)
            {
                writeConservedLog();
                logCounter++;
                
                conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-START*"+mouseInformation+"*"+miningID+":"+visualizationID;
                lastDragBarCount = logCounter;
                adjustedX = logX;
                adjustedY = logY;
            }
            else
                if(logX != adjustedX || logY != adjustedY)
                    conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*"+operation+"-END*"+mouseInformation+"*"+miningID+":"+visualizationID;
            return;
        }
        
        
        writeActionLog(windowName+"*MOUSE*"+operation+"*"+mouseInformation+"*"+miningID+":"+visualizationID);
    }
    
    //MOUSE WHEEL FROM MODULE
    static double totalRotation = 0;
    public static void writeMouseWheelLogFromModule(String windowName, double rotation, int miningID, int visualizationID)
    {
        setDiffTime();
        if(lastWheelCount != logCounter)
        {
            writeConservedLog();
            logCounter++;
            
            totalRotation = rotation;
            conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*WHEEL-START*"+miningID+":"+visualizationID;
            lastWheelCount = logCounter;
        }
        else
        {
            totalRotation += rotation;
            conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*WHEEL-END*"+totalRotation+"*"+miningID+":"+visualizationID;
        }
    }
    
    //MOUSE WHEEL
    public static void writeMouseWheelLog(String windowName, double rotation)
    {
        setDiffTime();
        if(lastWheelCount != logCounter)
        {
            writeConservedLog();
            logCounter++;
            
            totalRotation = rotation;
            conservedOperationStartLog = timeInformation+"*"+windowName+"*MOUSE*WHEEL-START";
            lastWheelCount = logCounter;
        }
        else
        {
            totalRotation += rotation;
            conservedOperationEndLog = timeInformation+"*"+windowName+"*MOUSE*WHEEL-END*"+totalRotation;
        }
    }
    
    public static double BenchMarkTest()
    {
        int TIME = 5000000;
        long start = System.currentTimeMillis();
        String str = "abcdefghijklmnopqrstuvwxyz";
        for (int i = 0; i < TIME; i++)
        {
            String a = str.substring(0, 13);
            String b = str.substring(13, 26);
            str = b + a;
        }
        long end = System.currentTimeMillis();
        return (end - start);
    }
    
    public static void createPClog(MainFrame mainFrame)
    {
        double spec = BenchMarkTest();
        
        int sizeX = (int)mainFrame.windowSizeX;
        int sizeY = (int)mainFrame.windowSizeY;
        int popY = (int)mainFrame.popSizeY;
        String windowInformation = sizeX+":"+(popY+sizeY);

        version = "TETDM*VERSION*"+mainFrame.version;
        pcSize = "SYSTEM*PC*SIZE*"+windowInformation;
        pcSpeed = "SYSTEM*PC*SPEED*"+spec;
    }

	
}
