package nxm.ucl.libg;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JFrame;
import javax.swing.JPanel;

import nxm.sys.inc.InternalUseOnly;
import nxm.sys.lib.MessageQueue;
import nxm.sys.lib.Midas;
import nxm.sys.lib.Results;
import nxm.sys.libg.MidasBean;
import nxm.sys.libg.MidasDisplay;

/** Used to duplicate BUG 1905

    NOTE: WHTabPanel does NOT currently support Java Serialization, even though it extends classes that support it.

    @author Wayne Dengel
    @since NeXtMidas 2.7.2
 */
@InternalUseOnly("Since NeXtMidas 3.5.2")
public class WHTabPanel extends JPanel {
  /** NOTE: this should be changed if the structure/fields of this class changes. */
  private static final long serialVersionUID = 2012122803331L; // for Serializable interface

  /** Message given when user tries to serialize a WHTabPanel object */
  @InternalUseOnly
  public static final String UNSERIALIZABLE_WHTABPANEL_OBJECT_MESSAGE =
      "nxm.ucl.libg.WHTabPanel does NOT currently support Java Serialization";

  /** The Panel background color */
  protected Color bg = null;
  /** The Panel foreground color */
  protected Color fg = null;
  /** JFrame object representing the new Window for the docked Panel */
  public JFrame jFrame = null;
  /** The Midas results object */
  protected Results MR = null;
  /** The Midas message queue */
  protected transient MessageQueue MQ = null;
  /** The raster display */
  protected MidasDisplay rasterDisplay = new MidasDisplay();
  /** The raster bean for the raster display */
  protected transient MidasBean rasterBean = null;
  /** The Midas context */
  protected transient Midas M = null;
  /** The Panel name */
  protected String name = null;
  /** The Panel tab ID ??? */
  protected int tabID = 0;
  /** State for whether or not the Panel is docked */
  public boolean docked = true;

  /** WHTabPanel Constructor
   *  @param M     the Midas context
   *  @param mq    the Midas message queue
   *  @param mr    the Midas results object
   *  @param bg    the Panel background color
   *  @param fg    the Panel foreground color
   *  @param name  the Panel name
   *  @param tabID the Panel tab ID ???
   */
  public WHTabPanel (Midas M, MessageQueue mq, Results mr, Color bg, Color fg, String name, int tabID) {
    this.M     = M;
    this.bg    = bg;
    this.fg    = fg;
    this.MR    = mr;
    this.MQ    = mq;
    this.name  = name;
    this.tabID = tabID;
  }

  /** Redock Panel back into the original main Window */
  public void redock () {
    jFrame.setVisible(false);
    docked = true;
  }

  /** Undock Panel from main Window
   *  @param screen ID referencing screen to undock Panel to
   *  @param x         the width of the new docked Panel
   *  @return Reference to graphics configuration for the new docked Panel
   */
  public GraphicsConfiguration undock (int screen, int x) {
    if (screen > -1) {
      GraphicsConfiguration gc = getDisplay(screen);
      if (jFrame != null) {
        jFrame.setVisible(false);
        jFrame.dispose();
        jFrame = null;
      }
      jFrame = new JFrame(this.name,gc);
      jFrame.add(this, BorderLayout.CENTER);
      jFrame.setSize(x, 855);
      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      Dimension frameSize  = jFrame.getSize();
      if (frameSize.height > screenSize.height) frameSize.height = screenSize.height;
      if (frameSize.width  > screenSize.width)  frameSize.width = screenSize.width;
      jFrame.setLocation( (screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
      jFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {redock();}});
      jFrame.setVisible(true);
      docked = false;
      return gc;
    }
    return null;
  }

  private GraphicsConfiguration getDisplay (int display) {
    GraphicsConfiguration gconf = null;
    if (display > -1) {
      try {
        gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[display].getConfigurations()[0];
      } catch (Exception e) {
        M.warning("WHTabPaneL: Unable to connect to display '" +display+"': "+ e);
      }
    }
    return gconf;
  }

  /** Get the Panel tab ID
   *  @return the Panel tab ID
   */
  public int getTabID () { return tabID; }

  /** Get the Panel name
   *  @return the Panel name
   */
  public String getName() { return name; }

  /** Overwrite default serialization for writeObject
   *  to throw an UnsupportedOperationException since Java Serialization currently not supported
   *
   *  @param oos Object Output Stream
   *  @throws IOException Exception thrown by writeObject
   */
  private void writeObject (ObjectOutputStream oos) throws IOException {
    throw new UnsupportedOperationException(UNSERIALIZABLE_WHTABPANEL_OBJECT_MESSAGE);
  }

  /** Overwrite default deserialization for readObject
   *  to throw an UnsupportedOperationException since Java Serialization currently not supported
   *
   *  @param ois Object Input Stream
   *  @throws ClassNotFoundException Exception thrown by readObject
   *  @throws IOException Exception thrown by readObject
   */
  private void readObject (ObjectInputStream ois) throws IOException, ClassNotFoundException {
    throw new UnsupportedOperationException(UNSERIALIZABLE_WHTABPANEL_OBJECT_MESSAGE);
  }

}