/*
 * Swogl - Swing meets OpenGL
 * 
 * Copyright 2007-2011 Marco Hutter - http://swogl.javagl.de
 */

package de.javagl.swogl.samples;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import de.javagl.swogl.Conditions;
import de.javagl.swogl.MouseEventConditions;
import de.javagl.swogl.SwoglApplication;
import de.javagl.swogl.SwoglApplications;
import de.javagl.swogl.SwoglContainer;
import de.javagl.swogl.interaction.Control;
import de.javagl.swogl.interaction.SpaceInteractionControl;
import de.javagl.swogl.layout.BrowseLayout3D;
import de.javagl.swogl.layout.BrowseLayoutControl;
import de.javagl.swogl.layout.GridLayout3D;
import de.javagl.swogl.layout.GridLayoutControl;
import de.javagl.swogl.layout.WheelLayout3D;
import de.javagl.swogl.layout.WheelLayoutControl;

/**
 * A small Swogl sample application, showing different capabilities
 * of Swogl, like the different implementations of the 
 * LayoutManager3D interface, and Look-and-Feel changes.
 */
public class SwoglSample extends JFrame
{
    /**
     * Entry point for this sample
     * 
     * @param args Not used
     */
    public static void main(String args[])
    {
        System.setProperty("sun.awt.noerasebackground", "true");
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new SwoglSample().setVisible(true);
            }
        });
    }
    
    // Some constants identifying the combo box selections
    private static final String NULL_LAYOUT_STRING = "(None)";
    private static final String WHEEL_LAYOUT_STRING = "WheelLayout";
    private static final String BROWSE_LAYOUT_STRING = "BrowseLayout";
    private static final String GRID_LAYOUT_STRING = "GridLayout";
    
    /**
     * The main SwoglContainer used in this sample
     */
    protected SwoglContainer swoglContainer;
    
    /**
     * A label displaying help texts
     */
    private JLabel helpLabel;
    
    /**
     * The current layout control
     */
    private Control currentControl = null;
    

    /**
     * Creates a new SwoglSample
     */
    public SwoglSample()
    {
        // Default initialization of the JFrame
        setSize(1024,768);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(createControlPanel(), BorderLayout.NORTH);

        // Create a SwoglApplication
        SwoglApplication swoglApplication = 
            SwoglApplications.createSwoglApplication();
        
        //System.out.println("Created "+swoglApplication);

        // Create a SwoglContainer for the SwoglApplication
        swoglContainer = SwoglContainer.create(swoglApplication);
        Component mainComponent = swoglContainer.getMainComponent();
        getContentPane().add(mainComponent, BorderLayout.CENTER);

        // Create the SwoglComponents for this sample and adds them to the
        // SwoglContainer
        swoglContainer.add(SwoglDemoComponents.createSwoglLogoComponent());
        swoglContainer.add(SwoglDemoComponents.createTableComponent());
        swoglContainer.add(SwoglDemoComponents.createTextComponent());
        swoglContainer.add(SwoglDemoComponents.createSplitPaneComponent());
        swoglContainer.add(SwoglDemoComponents.createTreeComponent());
        //swoglContainer.add(SwoglDemoComponents.createColoredTableComponent(200,50));
        
        setLayout(NULL_LAYOUT_STRING);
    }
    
    
    /**
     * Creates the main control panel for the sample
     */
    private JPanel createControlPanel()
    {
        JPanel controlPanel = new JPanel(new BorderLayout());
        controlPanel.setBorder(BorderFactory.createTitledBorder("Controls"));

        JPanel panel = new JPanel(new GridLayout(0,2));
        
        // Create the combo box for selecting the 3D layout
        panel.add(new JLabel("3D Layout"));
        Object options[] = new Object[]
        {
            NULL_LAYOUT_STRING,
            WHEEL_LAYOUT_STRING, 
            BROWSE_LAYOUT_STRING,
            GRID_LAYOUT_STRING,
        };
        final JComboBox layoutComboBox = new JComboBox(options);
        panel.add(layoutComboBox);
        layoutComboBox.addItemListener(new ItemListener()
        {
            @Override
            public void itemStateChanged(ItemEvent e)
            {
                setLayout(layoutComboBox.getSelectedItem().toString());
            }
        });

        // Create the combo box for selecting the look and feel
        panel.add(new JLabel("Look And Feel"));
        final UIManager.LookAndFeelInfo[] lookAndFeelInfos = 
            UIManager.getInstalledLookAndFeels();
        final String names[] = new String[lookAndFeelInfos.length];
        for (int i = 0; i < lookAndFeelInfos.length; i++) 
        {
            UIManager.LookAndFeelInfo lookAndFeelInfo = lookAndFeelInfos[i];
            names[i] = lookAndFeelInfo.getName();            
        }
        final JComboBox lnfComboBox = new JComboBox(names);
        panel.add(lnfComboBox);
        lnfComboBox.addItemListener(new ItemListener()
        {
            @Override
            public void itemStateChanged(ItemEvent e)
            {
                int index = lnfComboBox.getSelectedIndex();
                String className = lookAndFeelInfos[index].getClassName();
                setLookAndFeel(className);
            }
        });
        
        // Add the panel containing the comboBoxes to the control panel
        JPanel p2 = new JPanel(new BorderLayout());
        p2.add(panel, BorderLayout.NORTH);
        controlPanel.add(p2, BorderLayout.WEST);
        
        // Create the label that displays the info messages
        helpLabel = new JLabel();
        helpLabel.setPreferredSize(new Dimension(1,70));
        panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        panel.add(helpLabel, BorderLayout.CENTER);
        controlPanel.add(panel, BorderLayout.CENTER);
        
        return controlPanel;
    }

    /**
     * Set the L&F for this sample
     * 
     * @param lookAndFeelClassName The class name of the L&F
     */
    protected void setLookAndFeel(String lookAndFeelClassName)
    {
        try
        {
            UIManager.setLookAndFeel(lookAndFeelClassName);
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        SwingUtilities.updateComponentTreeUI(SwoglSample.this);
        repaint();
    }

    
    /**
     * Set the layout and info text that correspond to the
     * given layout identifier
     * 
     * @param layoutString The layout identifier
     */
    private void setLayout(String layoutString)
    { 
        if (currentControl != null)
        {
            currentControl.detachFrom(
                swoglContainer.getMainComponent());
        }
        swoglContainer.setMouseEventDispatchingConditions(
            MouseEventConditions.altDownCondition(), null);
        
        if (layoutString.equals(NULL_LAYOUT_STRING))
        {
            currentControl = new SpaceInteractionControl(swoglContainer);
            currentControl.attachTo(swoglContainer.getMainComponent());
            swoglContainer.setLayout3D(null);
            String text = 
                "<html>"+
                "No layout selected." + "<br>" +
                "ALT + Left mouse drags to rotate component" + "<br>" +
                "ALT + Middle mouse drags to scale component" + "<br>" +
                "ALT + Right mouse drags (or mouse wheel) to move component" + "<br>" +
                "</html>";
            helpLabel.setText(text);
            
        }
        else if (layoutString.equals(WHEEL_LAYOUT_STRING))
        {
            WheelLayout3D wheelLayout = new WheelLayout3D();
            currentControl = new WheelLayoutControl(wheelLayout);
            currentControl.attachTo(swoglContainer.getMainComponent());
            swoglContainer.setLayout3D(wheelLayout);
            String text = 
                "<html>"+
                "ALT + mouse wheel to rotate the components" + "<br>" +
                "</html>";
            helpLabel.setText(text);
        }
        else if (layoutString.equals(BROWSE_LAYOUT_STRING))
        {
            BrowseLayout3D browseLayout = new BrowseLayout3D();
            currentControl = new BrowseLayoutControl(browseLayout);
            currentControl.attachTo(swoglContainer.getMainComponent());
            swoglContainer.setLayout3D(browseLayout);
            String text = 
                "<html>"+
                "Press ALT to get an overview of the components" + "<br>" +
                "ALT + mouse wheel to scroll through the components" + "<br>" +
                "</html>";
            helpLabel.setText(text);
        }
        else if (layoutString.equals(GRID_LAYOUT_STRING))
        {
            GridLayout3D gridLayout = new GridLayout3D(2,3,10,10);
            currentControl = new GridLayoutControl(gridLayout, swoglContainer);
            currentControl.attachTo(swoglContainer.getMainComponent());
            swoglContainer.setLayout3D(gridLayout);
            String text = 
                "<html>"+
                "ALT + left double-click on component will zoom to " +
                "the component." + "<br>" +
                "ALT + right double-click will show the overview." + "<br>" +
                "</html>";
            helpLabel.setText(text);
        }
    }
    
}

