/*
 *  PHEX - The pure-java Gnutella-servent.
 *  Copyright (C) 2001 - 2004 Gregor Koukkoullis ( phex <at> kouk <dot> de )
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 *  --- CVS Information ---
 *  $Id: LookAndFeelUtils.java,v 1.7 2004/08/17 23:23:42 gregork Exp $
 */
package phex.gui.common;

import java.util.*;

import javax.swing.*;

import org.apache.commons.lang.SystemUtils;

import phex.utils.Logger;

import com.jgoodies.plaf.*;
import com.jgoodies.plaf.plastic.*;


/**
 * This class holds a collection of Themes with there associated LaF and overs
 * retrival methods.
 * 
 * @author gkoukkoullis
 */
public class LookAndFeelUtils
{
    private static ThemeInfo[] plasticThemes;
    
    public static UIManager.LookAndFeelInfo[] getAvailableLAFs()
    {
        List list = new ArrayList();
        
        if ( SystemUtils.IS_OS_MAC_OSX )
        {
            list.add( new UIManager.LookAndFeelInfo
                ("Macintosh", UIManager.getSystemLookAndFeelClassName() ) );
        }
        
        list.add( new UIManager.LookAndFeelInfo(
            "PlasticXP (default)", Options.PLASTICXP_NAME ) );
        
        list.add( new UIManager.LookAndFeelInfo(
            "Metal", "javax.swing.plaf.metal.MetalLookAndFeel") );
        //list.add( new UIManager.LookAndFeelInfo(
        //    "CDE/Motif", Options.EXT_MOTIF_NAME ) );
            
        if ( SystemUtils.IS_OS_WINDOWS )
        {
            // This LAF will use the Java 1.4.2 avaiable XP look on XP systems
            list.add( new UIManager.LookAndFeelInfo(
                "Windows", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel") );
        }
        
        /*
        
        // The Java 1.4.2 available GTK+ LAF seems to be buggy and is not working
        // correctly together with the Swing UIDefault constants. Therefore we need
        // to wait with support of it
        
        Class gtkLAFClass;
        try
        {
            gtkLAFClass =
                Class.forName("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
        }
        catch (ClassNotFoundException e)
        {
            gtkLAFClass = null;
        }
        if ( gtkLAFClass != null )
        {
            list.add( new UIManager.LookAndFeelInfo(
                "GTK", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") );
        }
        */
        UIManager.LookAndFeelInfo[] lafs = new UIManager.LookAndFeelInfo[ list.size() ];
        list.toArray( lafs );
        return lafs;
    }

    /**
     * @param lafClassName
     */
    public static ThemeInfo[] getAvailableThemes(String lafClassName)
    {
        if ( lafClassName.equals( Options.PLASTICXP_NAME ) )
        {
            initPlasticThemes();
            return plasticThemes;
        }
        return new ThemeInfo[0];
    }
    
    /**
     * @param lafClassName
     */
    public static ThemeInfo getCurrentTheme( String lafClassName )
    {
        if ( Options.PLASTICXP_NAME.equals( lafClassName ) )
        {
            PlasticTheme myCurrentTheme = PlasticLookAndFeel.getMyCurrentTheme();
            if ( myCurrentTheme == null )
            {
                return null;
            }
            Class clazz = myCurrentTheme.getClass();
            String name = clazz.getName();
            return new ThemeInfo( name, name );
        }
        return null;
    }
    
    public static void setCurrentTheme( String lafClassName, Object theme )
    {
        if ( lafClassName.equals( Options.PLASTICXP_NAME ) )
        {
            PlasticLookAndFeel.setMyCurrentTheme( (PlasticTheme)theme );
            try
            {
                // after setting the theme we must reset the PlasticLAF
                UIManager.setLookAndFeel( UIManager.getLookAndFeel() );
            }
            catch ( UnsupportedLookAndFeelException exp )
            {// this is not expected to happen since we reset a existing LAF
                Logger.logError( exp );
            }
        }
        GUIUtils.updateComponentsUI();
    }
    
    /**
     * Sets the look and feel with the given class name.
     * @param className the class name of the look and feel to set
     */
    public static void setLookAndFeel( String className )
    {
        try
        {
            Class lnfClass = Class.forName( className );
            setLookAndFeel( ( LookAndFeel ) ( lnfClass.newInstance() ) );
        }
        catch ( ClassNotFoundException exp )
        {
            Logger.logError( exp );
            JOptionPane.showMessageDialog( 
                GUIRegistry.getInstance().getMainFrame(),
                "Error loading Look & Feel " + exp, "Error", 
                JOptionPane.ERROR_MESSAGE );
        }
        catch ( IllegalAccessException exp )
        {
            Logger.logError( exp );
            JOptionPane.showMessageDialog( 
                GUIRegistry.getInstance().getMainFrame(),
                "Error loading Look & Feel " + exp, "Error", 
                JOptionPane.ERROR_MESSAGE );
        }
        catch ( InstantiationException exp )
        {
            Logger.logError( exp );
            JOptionPane.showMessageDialog( 
                GUIRegistry.getInstance().getMainFrame(),
                "Error loading Look & Feel " + exp, "Error", 
                JOptionPane.ERROR_MESSAGE );
        }
    }
    
    public static void setLookAndFeel( LookAndFeel laf )
    {
        try
        {
            // don't update LAF if already set...
            if ( laf.getID().equals( UIManager.getLookAndFeel().getID() ) )
            {
                return;
            }
            UIManager.setLookAndFeel( laf );
            GUIUtils.updateComponentsUI();
        }
        catch ( UnsupportedLookAndFeelException exp )
        {
            Logger.logError( exp );
            JOptionPane.showMessageDialog( 
                GUIRegistry.getInstance().getMainFrame(),
                "Error loading Look & Feel " + exp, "Error", 
                JOptionPane.ERROR_MESSAGE );
        }
    }
    
    private static void initPlasticThemes()
    {
        if ( plasticThemes == null )
        {
            String classPrefix = "com.jgoodies.plaf.plastic.theme.";
            plasticThemes = new ThemeInfo[18];
            plasticThemes[0] = new ThemeInfo( "BrownSugar", classPrefix + "BrownSugar" );
            plasticThemes[1] = new ThemeInfo( "DarkStar", classPrefix + "DarkStar" );
            plasticThemes[2] = new ThemeInfo( "DesertBlue", classPrefix + "DesertBlue" );
            if ( !LookUtils.IS_OS_WINDOWS_XP && LookUtils.IS_OS_WINDOWS_MODERN )
            {
                plasticThemes[3] = new ThemeInfo( "DesertBluer (default)",
                    classPrefix + "DesertBluer" );
            }
            else
            {
                plasticThemes[3] = new ThemeInfo( "DesertBluer", classPrefix + "DesertBluer" );
            }
            plasticThemes[4] = new ThemeInfo( "DesertGreen", classPrefix + "DesertGreen" );
            plasticThemes[5] = new ThemeInfo( "DesertRed", classPrefix + "DesertRed" );
            plasticThemes[6] = new ThemeInfo( "DesertYellow", classPrefix + "DesertYellow" );
            if ( LookUtils.IS_OS_WINDOWS_XP )
            {
                plasticThemes[7] = new ThemeInfo( "ExperienceBlue (default)",
                    classPrefix + "ExperienceBlue" );
            }
            else
            {
                plasticThemes[7] = new ThemeInfo( "ExperienceBlue",
                    classPrefix + "ExperienceBlue" );
            }
            plasticThemes[8] = new ThemeInfo( "ExperienceGreen", classPrefix + "ExperienceGreen" );
            plasticThemes[9] = new ThemeInfo( "Silver", classPrefix + "Silver" );
            
            if ( !LookUtils.IS_OS_WINDOWS_XP && !LookUtils.IS_OS_WINDOWS_MODERN )
            {
                plasticThemes[10] = new ThemeInfo( "SkyBlue (default)",
                    classPrefix + "SkyBlue" );
            }
            else
            {
                plasticThemes[10] = new ThemeInfo( "SkyBlue", classPrefix + "SkyBlue" );
            }
            plasticThemes[11] = new ThemeInfo( "SkyBluer", classPrefix + "SkyBluer" );
            plasticThemes[12] = new ThemeInfo( "SkyBluerTahoma", classPrefix + "SkyBluerTahoma" );
            plasticThemes[13] = new ThemeInfo( "SkyGreen", classPrefix + "SkyGreen" );
            plasticThemes[14] = new ThemeInfo( "SkyKrupp", classPrefix + "SkyKrupp" );
            plasticThemes[15] = new ThemeInfo( "SkyPink", classPrefix + "SkyPink" );
            plasticThemes[16] = new ThemeInfo( "SkyRed", classPrefix + "SkyRed" );
            plasticThemes[17] = new ThemeInfo( "SkyYellow", classPrefix + "SkyYellow" );
        }
    }
    
    public static class ThemeInfo
    {
        private String name;
        private String className;
        
        public ThemeInfo( String name, String className )
        {
            this.name = name;
            this.className = className;
        }
        
        /**
         * @return
         */
        public String getClassName()
        {
            return className;
        }

        /**
         * @return
         */
        public String getName()
        {
            return name;
        }
        
        public boolean equals( Object o )
        {
            if ( !(o instanceof ThemeInfo ) )
            {
                return false;
            }
            
            return className.equals( ((ThemeInfo)o).className );
            
        }
        
    }
}
