    /*
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the License). You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 *
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.updater;

import java.awt.*;
import java.util.Locale;
import javax.swing.*;
import java.io.*;
import java.beans.PropertyChangeListener;
import java.net.URL;


import javax.swing.border.LineBorder;

/**
 *
 * @author  phrebejk, akemr, Jiri Rechtacek
 * @version
 */
public class UpdaterFrame extends javax.swing.JPanel {

    int xxx = 0xFFFFFF;

    /** Operating system is Windows x */
    public static final int OS_WIN = 1;
    /** Operating system is Solaris. */
    public static final int OS_SOLARIS = 8;
    /** Operating system is Linux. */
    public static final int OS_LINUX = 16;
    /** Operating system is OS/2. */
    public static final int OS_OS2 = 1024;
    /** Operating system is unknown. */
    public static final int OS_OTHER = 65536;
    
    private static final String SPLASH_PATH = "org/netbeans/updater/resources/updatersplash"; // NOI18N
    private static final String UNDERLINE = "_";

    private static UpdaterFrame panel;

    private static boolean bigBounds = false;

    private static ModuleUpdater mu = null;
    
    private static boolean fromIDE = false;
    
    private static Window splashWindow;
    
    /** For external running Updater without GUI */
    private static boolean noSplash = false;
    
    /** Creates new form UpdaterFrame */
    public UpdaterFrame() {
        initComponents ();
        
        if ( addBorder() )
            setBorder(new LineBorder(stringToColor ("UpdaterFrame.LineBorder.Color", new Color(0, 0, 0))));
        
        loadSplash();
    }
    
    static final void center(Window c) {
        c.pack();

        GraphicsConfiguration gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        Rectangle bounds = gconf.getBounds();
        Dimension dialogSize = c.getSize();
        
        c.setLocation(bounds.x + (bounds.width - dialogSize.width) / 2,
                    bounds.y + (bounds.height - dialogSize.height) / 2);
    }

    static String getMainWindowTitle() {
        return Localization.getBrandedString("UpdaterFrame.Form.title");
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the FormEditor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jLabel3 = new javax.swing.JLabel();
        jTextArea1 = new javax.swing.JTextArea();
        textLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        setLayout(new java.awt.GridBagLayout());

        setBackground(stringToColor("UpdaterFrame.Background", new Color(6, 4, 100)));
        setBorder(new javax.swing.border.EmptyBorder(new java.awt.Insets(0, 0, 0, 0)));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        add(jLabel3, gridBagConstraints);

        jTextArea1.setBackground(stringToColor("UpdaterFrame.TextBackground", new Color (213, 204, 187)));
        jTextArea1.setEditable(false);
        jTextArea1.setForeground(stringToColor("UpdaterFrame.TextForeground", java.awt.Color.white));
        jTextArea1.setText(Localization.getBrandedString( "UpdaterFrame.jTextArea1.text" ));
        jTextArea1.setDisabledTextColor(stringToColor("UpdaterFrame.DisabledTextColor", java.awt.Color.white));
        jTextArea1.setOpaque(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(8, 14, 0, 14);
        add(jTextArea1, gridBagConstraints);

        textLabel.setFont(new java.awt.Font("Dialog", 1, 11));
        textLabel.setForeground(stringToColor("UpdaterFrame.TextForeground", java.awt.Color.white));
        textLabel.setText(Localization.getBrandedString("UpdaterFrame.textLabel.text"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(8, 14, 8, 14);
        add(textLabel, gridBagConstraints);

        progressBar.setPreferredSize(stringToDimension("UpdaterFrame.ProgressBar.PreferredSize", new Dimension (300, 20)));
        progressBar.setRequestFocusEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 14, 10, 14);
        add(progressBar, gridBagConstraints);

    }
    // </editor-fold>//GEN-END:initComponents

    protected void paintComponent (Graphics g) {
        if (isGradient ()) {
            Color outerColor = stringToColor ("UpdaterFrame.outerColor", new Color(230, 242, 234));
            Color centerColor = stringToColor ("UpdaterFrame.centerColor", Color.WHITE);
            int w = getWidth();
            int h = getHeight();

            // paint the background color.
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(new GradientPaint(0, 0, outerColor, w/2, 0, centerColor, true));
            g2d.fillRect(0, 0, w, h);
        } else {
            super.paintComponent (g);
        }
    }
    
    private static void showSplash () {
        
        if ((getOperatingSystem () == OS_WIN) ||
            (getOperatingSystem () == OS_SOLARIS) ||
            (getOperatingSystem () == OS_OS2) ||
            (getOperatingSystem () == OS_LINUX)) {
            // only some systems supports non-frame windows
            splashWindow = new SplashWindow();
        } else {        
            splashWindow = (Window)new SplashFrame();
        }

        // show splash
        javax.swing.SwingUtilities.invokeLater( 
                    new Runnable() {
                        public void run() {
                            splashWindow.setVisible(true);
                            splashWindow.toFront ();
                        }
                    });
    }
    
    /**
    * @param args the command line arguments
    */
    public static void main (String args[]) {
        if (args.length > 0) {
            cli (args);
        }
        
        panel = new UpdaterFrame ();
        
        if (!noSplash) {
            showSplash ();
        }

        mu = new ModuleUpdater();
        mu.start();

    }

    public static void runFromIDE (File[] files, PropertyChangeListener listener, String brandingToken) {
        fromIDE = true;        
        Localization.setBranding (brandingToken);
        panel = new UpdaterFrame ();
        panel.addPropertyChangeListener( listener );
        if (! noSplash) {
            showSplash();
        }
        
        mu = new ModuleUpdater();
        mu.setInstallOnly (files);
        mu.start();
    }

    void unpackingFinished() {
        runningFinished();
        /*
        ClassRunner runner = new ClassRunner(); 
        runner.start();
        */
    }

    void runningFinished() {
        if ( fromIDE ) {
            firePropertyChange("FINISHED", null, null);
            if (splashWindow != null) splashWindow.dispose();
        }
        else
            System.exit( 0 );
    }
    
    /** Tells the Localization class whether we are running from IDE or not
     */    
    boolean isFromIde() {
        return fromIDE;
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel3;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel textLabel;
    // End of variables declaration//GEN-END:variables


    static void setLabel( final String text ) {
        
        if (noSplash) return;

        final javax.swing.JLabel label = panel.textLabel;

        javax.swing.SwingUtilities.invokeLater( new Runnable() {
                                                    public void run() {
                                                        label.setText( text );
                                                    }
                                                });

    }


    static void setProgressRange( final long min, final long max ) {
        
        if (noSplash) return;

        bigBounds = max > 0xFFFF;

        final javax.swing.JProgressBar progressBar = panel.progressBar;
        final boolean bb = bigBounds;

        javax.swing.SwingUtilities.invokeLater( new Runnable() {
                                                    public void run() {
                                                        progressBar.setMinimum( bb ? (int)(min / 1024) : (int)min );
                                                        progressBar.setMaximum( bb ? (int)(max / 1024) : (int)max );
                                                    }
                                                });

    }

    static void setProgressValue( final long value ) {
        
        if (noSplash) return;

        final javax.swing.JProgressBar progressBar = panel.progressBar;
        final boolean bb = bigBounds;

        javax.swing.SwingUtilities.invokeLater( new Runnable() {
                                                    public void run() {
                                                        progressBar.setValue( bb ? (int)(value / 1024) : (int)value );
                                                    }
                                                });
    }
    
    /** Get the operating system on which the IDE is running.
    * @return one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
    */
    public static final int getOperatingSystem () {
        int operatingSystem = -1;
        String osName = System.getProperty ("os.name");
        if ( osName != null && osName.startsWith("Windows")) // NOI18N
            operatingSystem = OS_WIN;
        else if ("Solaris".equals (osName)) // NOI18N
            operatingSystem = OS_SOLARIS;
        else if (osName.startsWith ("SunOS")) // NOI18N
            operatingSystem = OS_SOLARIS;
        else if ("Linux".equals (osName)) // NOI18N
            operatingSystem = OS_LINUX;
        else if ("OS/2".equals (osName)) // NOI18N
            operatingSystem = OS_OS2;
        else
            operatingSystem = OS_OTHER;
        return operatingSystem;
    }
    
    /** Getter for property fromIDE.
     * @return Value of property fromIDE.
     */
    static boolean isFromIDE() {
        return fromIDE;
    }

    static UpdaterFrame getUpdaterFrame() {
        return panel;
    }
    
    static private Color stringToColor( String key, Color defcolor ) {
        try {
            String str = Localization.getBrandedString( key + "_R" );  // NOI18N
            int re = Integer.parseInt( str );
            
            str = Localization.getBrandedString( key + "_G" );  // NOI18N
            int gr = Integer.parseInt( str );
            
            str = Localization.getBrandedString( key + "_B" );  // NOI18N
            int bl = Integer.parseInt( str );
            
            return new Color ( re, gr, bl );
        } catch ( Exception e ) {
            return defcolor;
        }
    }
    
    static private Dimension stringToDimension (String key, Dimension defaultSize) {
        try {
            String str = Localization.getBrandedString( key + "_X" );  // NOI18N
            int x = Integer.parseInt( str );
            
            str = Localization.getBrandedString( key + "_Y" );  // NOI18N
            int y = Integer.parseInt( str );
            
            return new Dimension (x, y);
        } catch ( Exception e ) {
            return defaultSize;
        }
    }
    
    static private boolean addBorder() {
        return "true".equals( Localization.getBrandedString( "UpdaterFrame.hasBorder" ) ); // NOI18N
    }
    
    static private boolean isGradient () {
        return "true".equals (Localization.getBrandedString ("UpdaterFrame.isGradient")); // NOI18N
    }
    
    
    private void loadSplash() {
        URL lookup = Localization.getBrandedResource( SPLASH_PATH, ".gif" ); // NOI18N
        if ( lookup != null )
            jLabel3.setIcon( new ImageIcon( lookup ) );
    }
        
    static class SplashFrame extends JFrame {
        
        /** Creates a new SplashFrame */
        public SplashFrame () {
            super (getMainWindowTitle ());
            setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
            setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
            // add splash component
            getContentPane().add(panel);
            center(this);
        }
        
        public java.awt.Dimension getPreferredSize () {
            return stringToDimension("UpdaterFrame.Splash.PreferredSize", new Dimension (400, 280));
        }
    }
    
    
    static class SplashWindow extends Window {
        /** Creates a new SplashWindow */
        public SplashWindow () {
            super(new Frame());
            // add splash component
            setLayout (new java.awt.BorderLayout ());
            add(panel, java.awt.BorderLayout.CENTER);
            center(this);
        }

        public java.awt.Dimension getPreferredSize () {
            return stringToDimension("UpdaterFrame.Splash.PreferredSize", new Dimension (400, 280));
        }        
    }
    
    // copied from core/CLIOptions
    
    private static boolean isOption (String value, String optionName) {
        if (value == null) return false;
        
        if (value.startsWith ("--")) {
            return value.substring (2).equals (optionName);
        } else if (value.startsWith ("-")) {
            return value.substring (1).equals (optionName);
        }
        return false;
    }
    
    private static int cli(String[] args) {
        // let's go through the command line
        for (int i = 0; i < args.length; i++) {
            if (args[i] == null) {
                continue;
            }
            if (isOption (args[i], "nosplash")) { // NOI18N
                UpdaterFrame.noSplash = true;
            } else if (isOption (args[i], "locale")) { // NOI18N
                args[i] = null;
                String localeParam = args[++i];
                String language;
                String country = ""; // NOI18N
                String variant = ""; // NOI18N
                int index1 = localeParam.indexOf(":"); // NOI18N
                if (index1 == -1)
                    language = localeParam;
                else {
                    language = localeParam.substring(0, index1);
                    int index2 = localeParam.indexOf(":", index1+1); // NOI18N
                    if (index2 != -1) {
                        country = localeParam.substring(index1+1, index2);
                        variant = localeParam.substring(index2+1);
                    }
                    else
                        country = localeParam.substring(index1+1);
                }
                Locale.setDefault(new Locale(language, country, variant));
            } else if (isOption (args[i], "branding")) { // NOI18N
                args[i] = null;
                if (++i == args.length) {
                    System.err.println("Option --branding requires one argument.");
                    return 2;
                }
                String branding = args[i];
                if (branding.equals("-")) branding = null; // NOI18N
                try {
                    Localization.setBranding(branding);
                } catch (IllegalArgumentException iae) {
                    iae.printStackTrace();
                    return 1;
                }
            }
        }
        
        return 0;
    }
    
}
