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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTree;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.JTableHeader;

import org.jdesktop.swingx.JXStatusBar;
import org.jdesktop.swingx.plaf.basic.BasicStatusBarUI;

import de.javasoft.swing.JYDockingPort;
import de.javasoft.swing.JYDockingView;
import de.javasoft.swing.JYPropertyTable;
import de.javasoft.swing.jydocking.DockingManager;
import de.javasoft.swing.jydocking.IDockingConstants;
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.synthetica.addons.SyntheticaAddonsUtilities;
import de.javasoft.test.FourDockablesTest;

/**
 * Advanced docking demo.
 */
@SuppressWarnings("serial")
public class AdvancedDockingDemo extends JFrame
{  
  public static final String MAIN_VIEW = "mainViewID-AdvancedDockingDemo";
  public static final String TREE_VIEW = "treeViewID-AdvancedDockingDemo";
  public static final String PROPERTIES_VIEW = "propertiesViewID-AdvancedDockingDemo";
  public static final String INFO_VIEW = "infoViewID-AdvancedDockingDemo";
  public static final String OUTPUT_VIEW = "outputViewID-AdvancedDockingDemo";

  public AdvancedDockingDemo()
  {
    super("Advanced Docking Demo");
    DockingManager.setFloatingEnabled(true);    
    add(createContentPane(), BorderLayout.CENTER);
    add(createStatusBar(), BorderLayout.SOUTH);

    //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(TREE_VIEW);
        DockingManager.unregisterDockable(PROPERTIES_VIEW);
        DockingManager.unregisterDockable(INFO_VIEW);
        DockingManager.unregisterDockable(OUTPUT_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 - a view name (id) should be unique within your application
    JYDockingView mainView = createView(MAIN_VIEW, "Main Title", "MainTabText", null);
    initMainView(mainView);
    JYDockingView treeView = createView(TREE_VIEW, "Explorer Title", "ExplorerTabText", null);
    initTreeView(treeView);
    JYDockingView propertiesView = createView(PROPERTIES_VIEW, "Properties Title", "PropertiesTabText", null);
    initPropertiesView(propertiesView);
    JYDockingView infoView = createView(INFO_VIEW, "Info Title", "InfoTabText", null);
    initInfoView(infoView);
    JYDockingView outputView = createView(OUTPUT_VIEW, "Output Title", "OutputTabText", null);
    initOutputView(outputView);

    //create master docking port
    JYDockingPort viewport = new JYDockingPort();
    
    /* 
    //apply custom docking strategy to set tab placement
    //to TOP for all dockables
    IDockingStrategy ds = new DockingStrategy()
    {
      @Override
      protected IDockingPort createDockingPortImpl(IDockingPort base)
      {
        return new JYDockingPort(){
          @Override
          public int getTabPlacement()
          {
            return SwingConstants.TOP;
          }
        };
      }
    };
    DockingManager.setDockingStrategy(JYDockingPort.class, ds);
    */
    
    viewport.dock(mainView);
    mainView.dock(treeView, IDockingConstants.WEST_REGION, 0.3f);
    mainView.dock(outputView, IDockingConstants.SOUTH_REGION, .7f);
//@highlight
    mainView.dock(infoView, IDockingConstants.CENTER_REGION, 1f);
//@/highlight
    treeView.dock(propertiesView, IDockingConstants.SOUTH_REGION, 0.5f);

//@highlight
    //set tab placement TOP for mainView docking port only  
    mainView.getDockingPort().setTabPlacement(SwingConstants.TOP);
    mainView.getDockingPort().setSelectedTabIndex(0);
//@/highlight
    
    JPanel p = new JPanel(new BorderLayout(0, 0));
    p.setBorder(new EmptyBorder(5, 5, 5, 5));
    p.add(viewport, BorderLayout.CENTER);
    
    return p;
  }

  private void initMainView(JYDockingView mainView)
  {
//@highlight
    //make main view undraggable
    mainView.setDraggingEnabled(false);
//@/highlight
  }

  private void initTreeView(JYDockingView treeView)
  {  
    JScrollPane scroller = new JScrollPane(new JTree());
    scroller.setBorder(BorderFactory.createEmptyBorder());
    treeView.add(scroller);
  }  

  private void initPropertiesView(JYDockingView propertiesView)
  {  
    JYPropertyTable table = new JYPropertyTable();
    for (int i=0; i<8; i++)
      table.addProperty("Key " + (char)('A'+i), "Value " + (i+1));
    JScrollPane scroller = new JScrollPane(table);
    scroller.setBorder(BorderFactory.createEmptyBorder());
    JTableHeader th = new JTableHeader();
    th.setTable(table);
    scroller.setCorner(JScrollPane.UPPER_TRAILING_CORNER, th);    
    propertiesView.add(scroller);
  }  
  
  private void initInfoView(JYDockingView infoView)
  {  
  }  

  private void initOutputView(JYDockingView outputView)
  {
    JPanel p = new JPanel()
    {
      //modify panel background for bright themes only
      //to support LAF switch on runtime we override updateUI() 
      @Override
      public void updateUI()
      {
        if (SyntheticaAddonsUtilities.isDefaultTextBackgroundDark())
          //reset to default background color
          setBackground(null);
        else
          setBackground(new Color(0xFFFFE0));
        setForeground(null);
        super.updateUI();
      }
    };
    outputView.add(p);
  }
  
  /**
   * Create and initialize a view.
   */
  private JYDockingView createView(String name, String title, String tabText, String iconPath)
  {
    JYDockingView view = new JYDockingView(name, title, tabText);
    initView(view, iconPath);
    return view;
  }

  /**
   * Common view initialization.
   */
  private void initView(JYDockingView view, String iconPath)
  {
    view.addAction(new DefaultMinimizeAction(view));
    view.addAction(new DefaultMaximizeAction(view));

    if (!view.getID().equals(MAIN_VIEW))
    {
      view.addAction(new DefaultFloatAction(view));
      view.addAction(new DefaultCloseAction(view));
    }

    if (iconPath != null)
    {
      Icon icon = new ImageIcon(FourDockablesTest.class.getResource(iconPath));
      view.setIcon(icon);
    }

    JPanel p = new JPanel(new BorderLayout());
    view.setContentPane(p);

    view.getTitlebar().addMouseListener(new MouseAdapter()
    {
      @Override
      public void mousePressed(MouseEvent evt)
      {
        if (evt.getClickCount() == 2)
        {
          JYDockingView view = (JYDockingView) evt.getComponent().getParent();
          DockingManager.setMaximized(view, !DockingManager.isMaximized(view));
        }
      }
    });
  }
  
  /**
   * Create a simple statusbar.
   */
  private JXStatusBar createStatusBar()
  {
    JXStatusBar statusBar = new JXStatusBar();
    //do not add separators automatically
    statusBar.putClientProperty(BasicStatusBarUI.AUTO_ADD_SEPARATOR, Boolean.FALSE);
    statusBar.add(new JLabel("Ready"));
    //use dummy label to fill empty space
    statusBar.add(new JLabel(""), JXStatusBar.Constraint.ResizeBehavior.FILL);
    //create constraint to add space of 5 at components left and right side 
    JXStatusBar.Constraint ct = new JXStatusBar.Constraint(new Insets(0, 5, 0, 5));
    statusBar.add(new JSeparator(JSeparator.VERTICAL), ct);
    statusBar.add(new JLabel("INS"), ct);
    statusBar.add(new JSeparator(JSeparator.VERTICAL), ct);
    statusBar.add(new JLabel("Load"), ct);
    statusBar.add(new JProgressBar());
    //add the statusbar to the rootPane - some themes require this for proper appearance
    getRootPane().putClientProperty("Synthetica.statusBar", statusBar);    
    return statusBar;
  }
  
  /**
   * 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 AdvancedDockingDemo();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }
}
