/*
 * ******************************************************************************
 * Copyright (C) 2007, International Business Machines Corporation and others.
 * All Rights Reserved.
 * ******************************************************************************
 */
package com.ibm.icu.dev.tool.tzu;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;

/**
 * Loads the ICUTZU tool, GUI version.
 */
public class GUILoader {
    /**
     * The title for the application.
     */
    public static final String TITLE = "ICU4J Time Zone Update Utility (ICUTZU)";

    /**
     * The backup directory to store files.
     */
    private File backupDir;

    /**
     * The tool's home directory.
     */
    private File curDir;

    /**
     * The current logger.
     */
    private Logger logger;

    /**
     * Whether the paths frame has been closed or not.
     */
    private boolean pathClosed = false;

    /**
     * The frame that displays the path model component (<code>pathGUI</code>).
     */
    private JFrame pathFrame;

    /**
     * The component that allows the user to interact with the path model.
     */
    private PathComponent pathGUI;

    /**
     * The path model that stores all the paths and takes care of searching.
     */
    private PathModel pathModel;

    /**
     * Whether the results frame has been closed or not.
     */
    private boolean resultClosed = true;

    /**
     * The frame that displays the result model component (<code>resultGUI</code>).
     */
    private JFrame resultFrame;

    /**
     * The component that allows the user to interact with the result model.
     */
    private ResultComponent resultGUI;

    /**
     * The result model that stores all the results and takes care of updating.
     */
    private ResultModel resultModel;

    /**
     * The source model that stores all the update sources and accesses the repository for more
     * sources.
     */
    private SourceModel sourceModel;

    /**
     * The thread that partakes in the searching and updating.
     */
    private Thread workerThread = null;

    /**
     * Entry point for the GUI version of the tool.
     * 
     * @param curDir
     *            The base directory of the tool.
     * @param backupDir
     *            The location to store backups.
     * @param pathFile
     *            The file to load paths from.
     * @param resultFile
     *            The file to load/save results to/from.
     * @param tzFile
     *            The local timezone resource file.
     * @param iconFile
     *            The icon file.
     */
    public GUILoader(File curDir, File backupDir, File pathFile, File resultFile, File tzFile,
            File iconFile) {
        // set the backup dir
        this.backupDir = backupDir;
        this.curDir = curDir;

        // get the icon
        Image icon = Toolkit.getDefaultToolkit().getImage(iconFile.getAbsolutePath());

        // initialize the path list gui
        pathGUI = new PathComponent(this);
        pathFrame = new JFrame(TITLE + " - Directories to Search");
        pathFrame.getContentPane().add(pathGUI);
        pathFrame.pack();
        pathFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        pathFrame.setIconImage(icon);
        pathFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent event) {
                if (resultClosed)
                    System.exit(0);
                pathClosed = true;
            }
        });

        // initialize the result list gui
        resultGUI = new ResultComponent(this);
        resultFrame = new JFrame(TITLE + " - ICU4J Jar Files to Update");
        resultFrame.getContentPane().add(resultGUI);
        resultFrame.pack();
        resultFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        resultFrame.setIconImage(icon);
        resultFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent event) {
                if (pathClosed)
                    System.exit(0);
                resultClosed = true;
                makeThreadDead();
            }
        });

        // get the logger instance
        try {
            File logFile = new File(curDir.getPath(), "icutzugui.log");
            logger = Logger.getInstance(logFile, Logger.NORMAL, resultGUI, pathFrame);
        } catch (FileNotFoundException ex) {
            String error = "Could not open " + Logger.DEFAULT_FILENAME + " for writing.";
            System.out.println(error);
            JOptionPane.showMessageDialog(null, error, TITLE, JOptionPane.ERROR_MESSAGE);
            System.exit(-1);
        }

        // initialize the models
        resultModel = new ResultModel(logger, resultFile);
        pathModel = new PathModel(logger, pathFile);
        sourceModel = new SourceModel(logger, tzFile);

        // attach the models to the guis
        resultGUI.setResultModel(resultModel);
        pathGUI.setPathModel(pathModel);
        resultGUI.setSourceModel(sourceModel);

        // load all the paths into the path model
        try {
            // do it quietly
            int verb = logger.getVerbosity();
            logger.setVerbosity(Logger.QUIET);
            pathModel.loadPaths();
            logger.setVerbosity(verb);
        } catch (IOException ex) {
            // failed to load the directory search file
            pathModel.addAllDrives();
        } catch (IllegalArgumentException ex) {
            // failed to load the directory search file
            pathModel.addAllDrives();
        }

        // if the offline is not set to true, populate the list of available
        // timezone resource versions
        if (!"true".equalsIgnoreCase(System.getProperty("offline")))
            sourceModel.findSources();

        // make sure that search and update cancelation is disabled (since we
        // are initially neither updating nor searching, so there is nothing to
        // cancel)
        setCancelSearchEnabled(false);
        setCancelUpdateEnabled(false);

        // show the path list gui
        pathFrame.setVisible(true);
    }

    /**
     * Cancels a search.
     */
    public void cancelSearch() {
        makeThreadDead();
    }

    /**
     * Cancels an update.
     */
    public void cancelUpdate() {
        makeThreadDead();
    }

    /**
     * Searchs the selected paths in the path model.
     * 
     * @param indices
     *            Which paths in the path models to be used in the search.
     * @param subdirs
     *            Whether to search subdirectories.
     */
    public void search(final int[] indices, final boolean subdirs) {
        makeThreadDead();

        workerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    logger.printlnToBoth("Search started ...");
                    setCancelSearchEnabled(true);
                    setUpdateEnabled(false);
                    setSearchEnabled(false);
                    resultFrame.setVisible(true);
                    resultClosed = false;
                    pathModel.search(resultModel, indices, subdirs, curDir, backupDir);
                    logger.printlnToBoth("Search ended.");
                } catch (InterruptedException ex) {
                    logger.printlnToBoth("Search interrupted.");
                }
                setSearchEnabled(true);
                setUpdateEnabled(true);
                setCancelSearchEnabled(false);
            }
        });

        workerThread.start();
    }

    /**
     * Searchs all the paths in the path model.
     * 
     * @param subdirs
     *            Whether to search subdirectories.
     */
    public void searchAll(final boolean subdirs) {
        makeThreadDead();

        workerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    logger.printlnToBoth("Search started ...");
                    setCancelSearchEnabled(true);
                    setUpdateEnabled(false);
                    setSearchEnabled(false);
                    resultFrame.setVisible(true);
                    resultClosed = false;
                    pathModel.searchAll(resultModel, subdirs, curDir, backupDir);
                    logger.printlnToBoth("Search ended.");
                } catch (InterruptedException ex) {
                    logger.printlnToBoth("Search interrupted.");
                }
                setSearchEnabled(true);
                setUpdateEnabled(true);
                setCancelSearchEnabled(false);
            }
        });

        workerThread.start();
    }

    /**
     * Updates the selected results in the result model.
     * 
     * @param indices
     *            Which ICU4J jars in the result model to be used in the update.
     * @param updateURL
     *            The URL to use as the update for each ICU4J jar.
     */
    public void update(final int[] indices, final URL updateURL) {
        makeThreadDead();

        workerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    logger.printlnToBoth("Update started ...");
                    setCancelUpdateEnabled(true);
                    setUpdateEnabled(false);
                    setSearchEnabled(false);
                    resultModel.update(indices, updateURL, backupDir);
                    logger.printlnToBoth("Update ended.");
                } catch (InterruptedException ex) {
                    // we want to know what was last being updated, so do not
                    // change the status bar message
                    // try {
                    // logger.setStatus("Update interrupted.");
                    // } catch (InterruptedException e) {
                    // // once is enough
                    // }
                }
                setUpdateEnabled(true);
                setSearchEnabled(true);
                setCancelUpdateEnabled(false);
            }
        });

        workerThread.start();
    }

    /**
     * Updates all the results in the result model.
     * 
     * @param updateURL
     *            The URL to use as the update for each ICU4J jar.
     */
    public void updateAll(final URL updateURL) {
        makeThreadDead();

        workerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    logger.printlnToBoth("Update started ...");
                    setCancelUpdateEnabled(true);
                    setUpdateEnabled(false);
                    setSearchEnabled(false);
                    resultModel.updateAll(updateURL, backupDir);
                    logger.printlnToBoth("Update ended.");
                } catch (InterruptedException ex) {
                    // we want to know what was last being updated, so do not
                    // change the status bar message
                    // try {
                    // logger.setStatus("Update interrupted.");
                    // } catch (InterruptedException e) {
                    // // once is enough
                    // }
                }
                setUpdateEnabled(true);
                setSearchEnabled(true);
                setCancelUpdateEnabled(false);
            }
        });

        workerThread.start();
    }

    /**
     * Interrupts the worker thread and waits for it to finish.
     */
    private void makeThreadDead() {
        if (workerThread != null)
            try {
                workerThread.interrupt();
                workerThread.join();
            } catch (Exception ex) {
                // do nothing -- if an exception was thrown, the worker thread
                // must have already been dead, which is perfectly fine
            }
    }

    /**
     * Sets whether the cancel search button should be enabled.
     * 
     * @param value
     *            Whether the cancel search button should be enabled.
     */
    private void setCancelSearchEnabled(boolean value) {
        resultGUI.setCancelSearchEnabled(value);
    }

    /**
     * Sets whether the cancel update button should be enabled.
     * 
     * @param value
     *            Whether the cancel update button should be enabled.
     */
    private void setCancelUpdateEnabled(boolean value) {
        resultGUI.setCancelUpdateEnabled(value);
    }

    /**
     * Sets whether the search button should be enabled.
     * 
     * @param value
     *            Whether the search button should be enabled.
     */
    private void setSearchEnabled(boolean value) {
        pathGUI.setSearchEnabled(value);
    }

    /**
     * Sets whether the update button should be enabled.
     * 
     * @param value
     *            Whether the update button should be enabled.
     */
    private void setUpdateEnabled(boolean value) {
        resultGUI.setUpdateEnabled(value);
    }
}
