package de.javasoft.synthetica.democenter.examples.jydocking;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;

import de.javasoft.plaf.synthetica.SyntheticaLookAndFeel;
import de.javasoft.swing.JYDockingPort;
import de.javasoft.swing.JYDockingView;
import de.javasoft.swing.jydocking.DockingEvent;
import de.javasoft.swing.jydocking.DockingManager;
import de.javasoft.swing.jydocking.IDockable;
import de.javasoft.swing.jydocking.IDockingEventListener;
import de.javasoft.swing.plaf.jydocking.DefaultCloseAction;
import de.javasoft.swing.plaf.jydocking.DefaultFloatAction;
import de.javasoft.swing.plaf.jydocking.DefaultMaximizeAction;
import de.javasoft.swing.plaf.jydocking.DefaultMinimizeAction;
import de.javasoft.swing.plaf.jydocking.DockingButton;
import de.javasoft.swing.plaf.jydocking.DockingViewTitlebar;

/**
 * Demonstrates how to add a button to a view titlebar and to display 
 * the button for floating views only.
 */
@SuppressWarnings("serial")
public class AlwaysOnTopButtonDemo extends JFrame
{
  public static final String MAIN_VIEW = "MainViewID-AlwaysOnTopButtonDemo";
  public static final String EXPLORER_VIEW = "ExplorerViewID-AlwaysOnTopButtonDemo";
  public static final String INFO_VIEW = "InfoViewID-AlwaysOnTopButtonDemo";

  public AlwaysOnTopButtonDemo()
  {
    super("Button for floating Views");
    add(createContentPane());

    //clean up resources, recommended when Docking framework is used 
    //for a separate window just like the examples in the DemoCenter
    addWindowListener(new WindowAdapter()
    {
      @Override
      public void windowClosed(WindowEvent evt)
      {
        DockingManager.unregisterDockable(MAIN_VIEW);
        DockingManager.unregisterDockable(EXPLORER_VIEW);
        DockingManager.unregisterDockable(INFO_VIEW);
      }
    });
    
    //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setSize(640, 480);
    setLocationRelativeTo(null);        //center
    setVisible(true);
  }

  /**
   * Create content pane with three different views.
   */
  private JPanel createContentPane()
  {
    //create views - each view ID has to be unique within your application
    JYDockingView mainView = createMainView(MAIN_VIEW, "MainTitle", "MainTabText");
    JYDockingView explorerView = createView(EXPLORER_VIEW, "ExplorerTitle", "ExplorerTabText");
    JYDockingView infoView = createView(INFO_VIEW, "InfoTitle", "InfoTabText");

    //create main docking port - the container for the MainView.
    JYDockingPort viewport = new JYDockingPort();
    viewport.dock(mainView);

    //add sub views
    mainView.dock(explorerView, DockingManager.WEST_REGION, .3f);
    mainView.dock(infoView, DockingManager.SOUTH_REGION, .75f);

    //enable floating - drag and drop a view as a separate window 
    DockingManager.setFloatingEnabled(true);
    
    JPanel p = new JPanel(new BorderLayout(0, 0));
    p.setBorder(new EmptyBorder(5, 5, 5, 5));
    p.add(viewport, BorderLayout.CENTER);

    return p;
  }

  /**
   * Create the main view - with blocked center region.
   */
  public static JYDockingView createMainView(String name, String title, String tabText)
  {
    JYDockingView view = createView(name, title, tabText);
    //avoid dragging in the center region of the main view
    view.setTerritoryBlocked(DockingManager.CENTER_REGION, true);
    return view;
  }

  /**
   * Create additional views.
   */
  public static JYDockingView createView(String name, String title, String tabText)
  {
    JYDockingView view = new JYDockingView(name, title, tabText);
    initView(view);
    return view;
  }

  /**
   * Initialize specified view.
   */
  private static void initView(JYDockingView view)
  {
//@highlight
    //add action buttons to the titlebar
    if (!view.getID().equals(MAIN_VIEW))
    {          
      view.getTitlebar().add(new MyTitlePaneButton(view));
      //make button visible in floating mode only 
      view.addDockingListener(new FloatingListener());

      view.addAction(new DefaultMinimizeAction(view));
      view.addAction(new DefaultMaximizeAction(view));
      view.addAction(new DefaultFloatAction(view));
      view.addAction(new DefaultCloseAction(view));
    }  
//@/highlight

    //set an empty panel as view container/component 
    JPanel p = new JPanel(new BorderLayout());
    p.add(new JTree());
    view.setContentPane(p);
  }

  /**
   * Static main method for application startup. 
   */
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try
        {
          UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaStandardLookAndFeel");
          new AlwaysOnTopButtonDemo();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }
  
  
  /***************************************************************
  Custom title panel button
  ***************************************************************/   
  static class MyTitlePaneButton extends DockingButton
  {
    private static String buttonName = "CustomTitlePaneButton";
    private Color foreground;
    private Color activeForeground;

    public MyTitlePaneButton(JYDockingView view)
    {
      super(new MyButtonAction(view));
      setName(buttonName);
      foreground = view.getTitlebar().getTitleForeground();
      activeForeground = view.getTitlebar().getActiveTitleForeground();
    }

    @Override
    public Color getForeground()
    {
      //use titlebar foreground colors
      if (getParent() == null)
        return foreground;
      return ((DockingViewTitlebar) getParent()).isActive() ? activeForeground : foreground;
    }
  }  
  
  static class MyButtonAction extends AbstractAction
  {
    private JYDockingView view;

    public MyButtonAction(JYDockingView view)
    {
      this.view = view;
    }

    public void actionPerformed(ActionEvent evt)
    {
      AbstractButton button = (AbstractButton)evt.getSource();
      boolean selected = button.isSelected();

      //the action we want to achieve 
      Window w = DockingManager.getFloatingGroup(view).getFloatingWindow();
      w.setAlwaysOnTop(selected);
        
      //the action is related to a window, so update all custom buttons in floating view
      ArrayList<Component> buttons = new ArrayList<Component>();
      SyntheticaLookAndFeel.findComponents(MyTitlePaneButton.buttonName, w, buttons);
      for (Component c : buttons)
      {
        AbstractButton b = (AbstractButton)c;
        b.setSelected(selected);       
        //R means regular, S means selected (window always on top)   
        b.getAction().putValue(Action.NAME, selected ? "S" : "R");
      }
    }
  }
  
  /***************************************************************
  Listener to display button for floating views only
  ***************************************************************/   
  static class FloatingListener implements IDockingEventListener
  {
    public void dockingCompleted(final DockingEvent evt)
    {
      SwingUtilities.invokeLater(new Runnable()
      {        
        public void run()
        {
          IDockable dockable = evt.getDockable();
          AbstractButton b = (AbstractButton)SyntheticaLookAndFeel.findComponent(MyTitlePaneButton.buttonName, ((JYDockingView)dockable).getTitlebar());
          b.setVisible(DockingManager.isFloating(dockable));
          if (b.isVisible())
            b.getAction().actionPerformed(new ActionEvent(b, ActionEvent.ACTION_PERFORMED, ""));          
        }
      });
    }
    public void dockingCanceled(DockingEvent evt){}
    public void dockableRegistered(DockingEvent evt){}
    public void dockableUnregistered(DockingEvent evt){}
    public void undockingStarted(DockingEvent evt){}
    public void undockingCompleted(DockingEvent evt){}
    public void dragStarted(DockingEvent evt){}
    public void dropStarted(DockingEvent evt){}    
  }
  
}
