/*
 * BIGraph.java
 *
 * Copyright © 1994-2004, Oracle. All rights reserved. Oracle grants
 * you ("Licensee") a non-exclusive, royalty-free, worldwide license to use,
 * modify and redistribute this software in source and binary code form, provided
 * that (i) this copyright notice and license appear on all copies of the
 * software; (ii) Licensee does not utilize the software in a manner disparaging
 * to Oracle; and (iii) Licensee does not utilize the software in a manner that
 * violates the terms of any Licensee agreement with Oracle.
 */
package samples.javaclient;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.KeyEvent;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;

import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

import oracle.bali.ewt.button.DialogButtonBar;
import oracle.bali.ewt.border.GrayPane;
import oracle.bali.ewt.graphics.ImageUtils;
import oracle.bali.ewt.util.WindowUtils;
import oracle.bali.ewt.wizard.ImageWizardPage;
import oracle.bali.ewt.wizard.WizardEvent;
import oracle.bali.ewt.wizard.WizardListener;

import oracle.dss.datautil.gui.panel.DefaultStandardPanel;
import oracle.dss.datautil.gui.panel.StandardPanel;
import oracle.dss.queryBuilder.QueryBuilder;
import oracle.dss.bicontext.ManagerFactory;
import oracle.dss.dataSource.common.Query;
import oracle.dss.dataSource.client.QueryManager;
import oracle.dss.metadataManager.client.MetadataManager;
import oracle.dss.util.MetadataMap;
import oracle.dss.util.LayoutContext;
import oracle.dss.dataView.ViewMouseEvent;
import oracle.dss.dataView.ViewMouseListenerAdapter;
import oracle.dss.datautil.gui.DefaultBuilderDialog;
import oracle.dss.graph.Graph;
import oracle.dss.graph.gui.BasePanel;
import oracle.dss.graph.gui.GraphLayout;
import oracle.dss.graph.gui.GraphToolBar;
import oracle.dss.graph.gui.GraphType;
import oracle.dss.graph.gui.GroupAxis;
import oracle.dss.graph.gui.Legend;
import oracle.dss.graph.gui.PlotArea;
import oracle.dss.graph.gui.Title;
import oracle.dss.graph.gui.ValueAxis;

/** 
 * <P>
 * The BIGraph extends JFrame.
 * BIGraph allows the user to step through the query 
 * builder and Graph format panel to generate a Graph bean along with the 
 * specified query.
 * <P>
 * In addition the wizard also provides a menu to individually access the Graph
 * format panel. It also adds the Graph toolbar and updates the status bar with 
 * the name of the selected component
 */ 
public class BIGraph extends JFrame implements WizardListener {
  private JMenu m_sampleMenu;           // Menu for sample
  private JMenuItem m_graphMenu;        // Menu item for graph
  private JMenuItem m_graphTypeMenu;    // Menu item for graph type panel
  private JMenuItem m_legendMenu;       // Menu item for legend panel
  private JMenuItem m_titleMenu;        // Menu item for title panel
  private JMenuItem m_plotAreaMenu;     // Menu item for  plotarea panel
  private JMenuItem m_xAxisMenu;        // Menu item for X1Axis or O1Axis panel
  private JMenuItem m_y1AxisMenu;       // Menu item for Y1Axis panel
  private JMenuItem m_y2AxisMenu;       // Menu item for Y2Axis panel
  private JMenuItem m_layoutMenu;       // Menu item for layout panel 
  
  private Graph       m_graph;            // instance of Graph 
  private GraphToolBar m_graphToolBar;    // instance of Graph toolbar
  private GraphType   m_graphTypePanel;   // instance of Graph type panel
  private Legend      m_legendPanel;      // instance of legend panel
  private Title       m_titlePanel;       // instance of title panel
  private PlotArea    m_plotAreaPanel;    // instance of plotarea panel
  private GroupAxis   m_o1AxisPanel;      // instance of GroupAxis panel
  private ValueAxis   m_x1AxisPanel;      // instance of ValueAxis panel
  private ValueAxis   m_y1AxisPanel;      // instance of ValueAxis panel
  private ValueAxis   m_y2AxisPanel;      // instance of ValueAxis panel
  private GraphLayout m_graphLayoutPanel; // instance of layout panel
  private ImageWizardPage currentPage = null;  // instance of a wizard page
  private QueryBuilder m_queryBuilder;   // instance of QueryBuilder
  private BIFrame m_frame;
  private JPanel m_panel;

    
  /** 
   * Constructor for BIGraph.
   *
   * @param frame The parent frame.
   */ 
  public BIGraph(BIFrame parentFrame, String title) {
    super(title);
    m_frame = parentFrame;
    init();
  }

  /**
   * Implementing wizard listener interface
   *
   * @param e represents instance of WizardEvent
   */
  public void wizardSelectionChanged(WizardEvent e) {
    ImageWizardPage page = (ImageWizardPage) e.getPage();
    if (page == null) {
      return;
    }
    String nextID = ((StandardPanel)page.getInteractiveArea()).getId();
    
    String m_currentID = "";

    if (currentPage != null) {
      m_currentID = ((StandardPanel) currentPage.getInteractiveArea()).getId();
    }

    // if id of next page equals Layout panel id then apply graph type
    // and set up the graph layout panel
    if( nextID.equals(QueryBuilder.LAYOUT_PANEL_ID) ) {
      m_graphTypePanel.apply();

      m_graphLayoutPanel = new GraphLayout();
      m_graphLayoutPanel.setGraph(m_graph);
      
      m_graphLayoutPanel.setLayoutContext((LayoutContext) 
                                        m_queryBuilder.getQuery());
                                        
      m_graphLayoutPanel.setPagingControlVisible(true);
      m_queryBuilder.setViewLayoutPanel(m_graphLayoutPanel);
      
      _addGraphFormatPanels(m_graph.getGraphType());
    }

    // if id equals Legend id apply legend panel changes on graph
    else if(m_currentID.equals("Legend")) {
      m_legendPanel.apply();
    }

    // if id equals PlotArea id apply plotarea panel changes on graph
    else if(m_currentID.equals("PlotArea")) {
      m_plotAreaPanel.apply();
      
      // check for assignedToY2 attribute
      if( _isDualY(m_graph.getGraphType()) ) {
        if(m_y1AxisPanel != null) {
          m_y1AxisPanel.setGraph(m_graph);
        }
        if(m_y2AxisPanel != null) {
          m_y2AxisPanel.setGraph(m_graph);
        }
      }
    }

    // if id equals title id apply title panel changes on graph
    else if(m_currentID.equals("Title")) {
      m_titlePanel.apply();
    }

    // if id equals X1Axis id apply ValueAxis panel changes on graph
    else if(m_currentID.equals("X1-Axis")) {
      m_x1AxisPanel.applyAfterCheck();
    }

    // if id equals O1Axis id apply GroupAxis panel changes on graph
    else if(m_currentID.equals("O1-Axis")) {
      m_o1AxisPanel.applyAfterCheck();
    }

    // if id equals Y1Axis id apply ValueAxis panel changes on graph
    else if(m_currentID.equals("Y1-Axis")) {
      m_y1AxisPanel.applyAfterCheck();
    }
    // if id equals Y2Axis id apply ValueAxis panel changes on graph
    else if(m_currentID.equals("Y2-Axis")) {
      m_y2AxisPanel.applyAfterCheck();
    }
    m_currentID = nextID;
    currentPage = page;
  }
  
  /**
   * Implementing wizard listener interface
   *
   * @param e represents instance of WizardEvent
   */
  public void wizardValidatePage(WizardEvent e) {
  }

  /**
   * Implementing wizard listener interface
   *
   * @param e represents instance of WizardEvent
   */
  public void wizardApplyState(WizardEvent e) {
  }

  /**
   * Implementing wizard listener interface
   *
   * @param e represents instance of WizardEvent
   */
  public void wizardCanceled(WizardEvent e) {
    
    /**
    if(m_graph != null) {
      m_graph.cleanUp();
      m_graph = null;
    }*/

    ((DefaultBuilderDialog)m_queryBuilder.getContainer()).getWizard()
                                       .removeWizardListener(this);
  }

  /**
   * Implementing wizard listener interface
   *
   * @param e represents instance of WizardEvent
   */
  public void wizardFinished(WizardEvent e) {
    
    wizardSelectionChanged(e);
    if (m_graphTypePanel != null)
      m_graphTypePanel.apply();
    if(m_graph != null) {
      m_panel.removeAll();
      m_panel.setLayout(new BorderLayout());
      // add graph to display panel
      m_panel.add(m_graph, BorderLayout.CENTER);
      m_graphToolBar= new GraphToolBar(m_graph);
      // add graph toolbar to display panel
      m_panel.add( m_graphToolBar, BorderLayout.NORTH );
      m_panel.invalidate();
      m_panel.validate();
      m_panel.repaint();
      _updateMenuBar(m_graph.getGraphType());
    }
  }
    
  /**
   * Initialize the user interface.
   */
  protected void init() {
    
    JMenuBar menuBar = new JMenuBar();
    // adding option to create graph 
    m_sampleMenu = new JMenu("Modifying graphs");
    m_graphMenu = new JMenuItem("New Graph");
    m_graphMenu.setMnemonic('G');
    m_sampleMenu.add(m_graphMenu);
    menuBar.add(m_sampleMenu);

    // invoking panel to change graph type
    m_graphTypeMenu = new JMenuItem("Change Graph Type");
    m_graphTypeMenu.setMnemonic('G');
    m_graphTypeMenu.setEnabled(false);
    m_sampleMenu.add(m_graphTypeMenu);

    // invoking panel to change legend properties
    m_legendMenu = new JMenuItem("Change Legend");
    m_legendMenu.setMnemonic('L');
    m_legendMenu.setEnabled(false);
    m_sampleMenu.add(m_legendMenu);

    // invoking panel to change title, subtitle and Footnote properties 
    m_titleMenu = new JMenuItem("Change Title");
    m_titleMenu.setMnemonic('T');
    m_titleMenu.setEnabled(false);;
    m_sampleMenu.add(m_titleMenu);

   // invoking panel to change plotArea properties
    m_plotAreaMenu = new JMenuItem("Change PlotArea");
    m_plotAreaMenu.setMnemonic('P');
    m_plotAreaMenu.setEnabled(false);
    m_sampleMenu.add(m_plotAreaMenu);

   // invoking panel to change X axis properties
    m_xAxisMenu = new JMenuItem("Change X-Axis");
    m_xAxisMenu.setMnemonic('X');
    m_xAxisMenu.setEnabled(false);
    m_sampleMenu.add(m_xAxisMenu);

   // invoking panel to change Y1 axis properties
    m_y1AxisMenu = new JMenuItem("Change Y1-Axis");
    m_y1AxisMenu.setMnemonic('Y');
    m_y1AxisMenu.setEnabled(false);
    m_sampleMenu.add(m_y1AxisMenu);

   // invoking panel to change Y2 axis properties
    m_y2AxisMenu = new JMenuItem("Change Y2-Axis");
    m_y2AxisMenu.setMnemonic('2');
    m_y2AxisMenu.setEnabled(false);
    m_sampleMenu.add(m_y2AxisMenu);

   // invoking panel to change the layout of the graph
    m_layoutMenu = new JMenuItem("Change Graph Layout");
    m_layoutMenu.setMnemonic('r');
    m_layoutMenu.setEnabled(false);
    m_sampleMenu.add(m_layoutMenu);
        
    // when the graph menuitem is selected, open the graph wizard
    m_graphMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showGraphWizard();
      }
    });
    
    // when the graphtype menuitem is selected, open the graphtype panel 
    // in a dialog
    m_graphTypeMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showGraphTypeDialog();
      }
    });

    // when the legend menuitem is selected, open the legend panel in a dialog
    m_legendMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showLegendDialog();
      }
    });

    // when the titles menuitem is selected, open the title panel in a dialog
    m_titleMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showTitleDialog();
      }
    });

    // when the plotarea menuitem is selected, open the plotarea panel in a 
    // dialog
    m_plotAreaMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showPlotAreaDialog();
      }
    });

    // when the XAxis menuitem is selected, open either the GroupAxis or 
    // ValueAxis panel in a dialog based on the graphtype
    m_xAxisMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showXAxisDialog();
      }
    });

    // when the Y1Axis menuitem is selected, open the Y1Axis panel in a dialog
    m_y1AxisMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showY1AxisDialog();
      }
    });

    // when the Y2Axis menuitem is selected, open the Y2Axis panel in a dialog
    m_y2AxisMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showY2AxisDialog();
      }
    });

    // when the Graph Layout menuitem is selected, open the Graph Layout panel 
    // in a dialog
    m_layoutMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        _showLayoutDialog();
      }
    });

    m_panel = new JPanel();
    m_panel.setLayout(new BorderLayout());
    
    // put all of these into the frame
    setJMenuBar(menuBar);
    getContentPane().removeAll();
    getContentPane().add(m_panel, BorderLayout.CENTER);
  
    // add a listener to listen for the window closing event
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        cleanUp();
      }
    });
    
    // show graph wizard on startup
    _showGraphWizard();
  }

  /**
   * This method cleans up before returning to the main menu
   */
  protected void cleanUp() {
    
    // Free resources
    if(m_graph != null) {
      m_graph.setDataSource(null);
      // removing graph and tool bar
      m_panel.remove(m_graph);
      m_panel.remove(m_graphToolBar);
      // calling cleanUp()
      m_graph.cleanUp();
      m_graphToolBar.cleanUp();
      // setting unused instance to null
      m_graph = null;
      m_graphToolBar = null;
      m_queryBuilder = null;
    } 
    dispose();
  }


  /**
   * shows GraphType panel in a dialog that lets application user choose the 
   * graph type
   */
  private void _showGraphTypeDialog() {
    if(m_graphTypePanel == null) {
      m_graphTypePanel = new GraphType(m_graph);
    }
    else {
      m_graphTypePanel.setGraph(m_graph);
    }
    PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this),"Graph Type", 
                                    m_graphTypePanel);
    d.show();
  }

  /**
   * shows  legend panel in a dialog that lets application user set properties 
   * on the Legend
   */
  private void _showLegendDialog() {
    if(m_legendPanel == null) {
      m_legendPanel = new Legend(m_graph);
    }
    else {
      m_legendPanel.setGraph(m_graph);
    }
    PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this),"Legend",
                                     m_legendPanel);
    d.show();
  }
  
  /**
   * shows titles panel in a dialog that lets application user set properties on
   * the title, subtitle and footnote
   */
  private void _showTitleDialog() {
    if(m_titlePanel == null) {
      m_titlePanel = new Title(m_graph);
    }
    else {
      m_titlePanel.setGraph(m_graph);
    }
    PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this), "Title", 
                                    m_titlePanel);
    d.show();
  }
  
  /**
   * shows plotarea panel in a dialog that lets application user set properties
   * on the PlotArea
   */
  private void _showPlotAreaDialog() {
    if(m_plotAreaPanel == null) {
      m_plotAreaPanel = new PlotArea(m_graph);
    }
    else {
      m_plotAreaPanel.setGraph(m_graph);
    }
    PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this),"PlotArea", 
                                    m_plotAreaPanel);
    d.show();
  }
  
  /**
   * shows GroupAxis or ValueAxis panel in a dialog that lets application user 
   * set properties on the O1 or X1 axis depending on the graph type
   */
  private void _showXAxisDialog() {
    // check if graphtype supports ordinal axis i.e. Graph type is bar, line, 
    // area, radar, stock, etc.
    if( m_graph.isO1AxisSupported()) {
      if(m_o1AxisPanel == null) {
        m_o1AxisPanel = new GroupAxis(m_graph);
      }
      else {
        m_o1AxisPanel.setGraph(m_graph);
      }
      PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this), "X Axis", 
                                      m_o1AxisPanel);
      d.show();
    }
    // if graph type supports value axis i.e. graph type is scatter, bubble, 
    // polar, etc.
    else {
      if(m_x1AxisPanel == null) {
        m_x1AxisPanel = new ValueAxis(m_graph, Graph.X1AXIS);
      }
      else {
        m_x1AxisPanel.setGraph(m_graph);
      }
      PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this),"X Axis", 
                                      m_x1AxisPanel);
      d.show();
    }  
  }
  
  /**
   * shows Y1Axis panel in a dialog that lets application user set properties on
   * the Y1Axis 
   */
  private void _showY1AxisDialog() {
    if(m_y1AxisPanel == null) {
      m_y1AxisPanel = new ValueAxis(m_graph, Graph.Y1AXIS);
    }
    else {
      m_y1AxisPanel.setGraph(m_graph);
    }
    PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this), "Y1 Axis",
                                     m_y1AxisPanel);
    d.show();
  }
  
  /**
   * shows Y2Axis panel in a dialog that lets application user set properties on
   * the Y2Axis
   */
  private void _showY2AxisDialog() {
   if(m_y2AxisPanel == null) {
     m_y2AxisPanel = new ValueAxis(m_graph, Graph.Y2AXIS);
   }
   else {
     m_y2AxisPanel.setGraph(m_graph);
   }
   PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this), "Y2 Axis", 
                                    m_y2AxisPanel);
   d.show();
  }
  
  /**
   * shows layout panel in a dialog that lets application user change the Graph
   * layout
   */
  private void _showLayoutDialog() {
    // Create the layout panel and update the key properties
     m_graphLayoutPanel = new GraphLayout();  
     m_graphLayoutPanel.setGraph(m_graph);     
     m_graphLayoutPanel.setPagingControlVisible(true);
     m_graphLayoutPanel.setLayoutContext((LayoutContext) 
                                        m_queryBuilder.getQuery());

     PanelDialog d = new PanelDialog(WindowUtils.parentFrame(this),"GraphLayout",
                                    m_graphLayoutPanel);
     d.show();
  }
  
  /**
   * shows Graph wizard that contains Query Builder and graph format panels
   * This wizard allows the user to follow the steps of creating a query and  
   * then creating a new graph based on the query 
   */
  private void _showGraphWizard() {
    try {

    // create query builder and add wizard listener
    m_queryBuilder = new QueryBuilder(this);
    m_queryBuilder.setMetadataManager(m_frame.getMetadataManager());
    Query query = _makeQuery(m_frame.getMetadataManager());
    m_queryBuilder.setQuery(query);
    m_queryBuilder.setMode(QueryBuilder.WIZARD);

    // if graph is not null call cleanUp()
    /*
    if(m_graph != null) {
      // removing graph and tool bar
      m_panel.remove(m_graph);
      m_graph.cleanUp();
      m_graph = null;
    }*/
    m_graph = new Graph();
    m_graph.setDataSource(query);
    m_queryBuilder.initialize();
    
    // adding graph type panel to query builder wizard    
    StandardWizardPanel wizPanel = new StandardWizardPanel ("GraphType");
    if(m_graphTypePanel == null)
      m_graphTypePanel = new GraphType(m_graph);
    else
      m_graphTypePanel.setGraph(m_graph);
    wizPanel.add (m_graphTypePanel);
    m_queryBuilder.addPanel((StandardPanel) wizPanel, 
                            QueryBuilder.LAYOUT_PANEL_ID);

    // adding the wizard listener
    ((DefaultBuilderDialog)m_queryBuilder.getContainer()).getWizard()
                                                       .addWizardListener(this);

    m_queryBuilder.run();
    }
    catch (Exception ex) {
      m_frame.showExceptionDialog(this, ex);
    }
  }

  /**
   * add only those panels to wizard that are supported by the current graph type
   */
  private void _addGraphFormatPanels(int graphType)
  {
    StandardWizardPanel wizPanel = null;
    
    if(m_queryBuilder == null)
      return;

    // remove all the panels  
    m_queryBuilder.removePanel("Legend");
    m_queryBuilder.removePanel("Title");
    m_queryBuilder.removePanel("PlotArea");
    m_queryBuilder.removePanel("O1-Axis");
    m_queryBuilder.removePanel("X1-Axis");
    m_queryBuilder.removePanel("Y1-Axis");
    m_queryBuilder.removePanel("Y2-Axis");
    
    if(_isLegendSupported(graphType)) {
      wizPanel = new StandardWizardPanel ("Legend");
      if(m_legendPanel == null) {
        m_legendPanel = new Legend(m_graph);
      }
      else {
        m_legendPanel.setGraph(m_graph);
      }
      wizPanel.add (m_legendPanel);
      m_queryBuilder.addPanel((StandardPanel) wizPanel, null);
    }

    wizPanel = new StandardWizardPanel ("Title");
    if(m_titlePanel == null) {
      m_titlePanel = new Title(m_graph);
    }
    else {
      m_titlePanel.setGraph(m_graph);
    }
    wizPanel.add (m_titlePanel);
    m_queryBuilder.addPanel((StandardPanel) wizPanel, null);

    wizPanel = new StandardWizardPanel ("PlotArea");
    if(m_plotAreaPanel == null) {
      m_plotAreaPanel = new PlotArea(m_graph);
    }
    else {
      m_plotAreaPanel.setGraph(m_graph);
    }
    wizPanel.add (m_plotAreaPanel);
    m_queryBuilder.addPanel((StandardPanel) wizPanel, null);
 
    if(! _isPie(graphType)) {
      if(m_graph.isO1AxisSupported()) {
        wizPanel = new StandardWizardPanel ("O1-Axis");
        if(m_o1AxisPanel == null) {
          m_o1AxisPanel = new GroupAxis(m_graph);
        }
        else {
          m_o1AxisPanel.setGraph(m_graph);
        }
        wizPanel.add (m_o1AxisPanel);
      }
      else {
        wizPanel = new StandardWizardPanel ("X1-Axis");
        if(m_x1AxisPanel == null) {
          m_x1AxisPanel = new ValueAxis(m_graph, Graph.X1AXIS);
        }
        else {
          m_x1AxisPanel.setGraph(m_graph);
        }
        wizPanel.add (m_x1AxisPanel);
      }
      m_queryBuilder.addPanel((StandardPanel) wizPanel, null);

      wizPanel = new StandardWizardPanel ("Y1-Axis");
      if(m_y1AxisPanel == null) {
        m_y1AxisPanel = new ValueAxis(m_graph, Graph.Y1AXIS);
      }
      else {
        m_y1AxisPanel.setGraph(m_graph);
      }
      wizPanel.add (m_y1AxisPanel);
      m_queryBuilder.addPanel((StandardPanel) wizPanel, null);
    }

    if(_isDualY(graphType)) {
      wizPanel = new StandardWizardPanel ("Y2-Axis");
      if(m_y2AxisPanel == null) {
        m_y2AxisPanel = new ValueAxis(m_graph, Graph.Y2AXIS);
      }
      else {
        m_y2AxisPanel.setGraph(m_graph);
      }
      wizPanel.add (m_y2AxisPanel);
      m_queryBuilder.addPanel((StandardPanel) wizPanel, null);
    }
    
    // refresh the query builder wizard
    m_queryBuilder.getContainer().refresh();
  }
  
  /**
   * enable or disable format menus based on the graph type
   *
   * @param graphType integer representing the graph type
   */
  private void _updateMenuBar(int graphType) {
  
    m_graphTypeMenu.setEnabled(true);
    m_titleMenu.setEnabled(true);
    m_plotAreaMenu.setEnabled(true);
    m_layoutMenu.setEnabled(true);

    if(_isLegendSupported(graphType)) {
      m_legendMenu.setEnabled(true);
    }
    else {
      m_legendMenu.setEnabled(false);
    }

    // Pie graphs do not display axes
    if(_isPie(graphType)) {
      m_xAxisMenu.setEnabled(false);
      // if graph is Pie-Bar then it supports Y1Axis
      if((graphType != Graph.PIE_BAR) && (graphType != Graph.RING_BAR)) {
        m_y1AxisMenu.setEnabled(false);
      }
      else {
        m_y1AxisMenu.setEnabled(true);
      }
    }
    else {
      m_xAxisMenu.setEnabled(true);
      m_y1AxisMenu.setEnabled(true);
    }

    if(_isDualY(graphType)) {
      m_y2AxisMenu.setEnabled(true);
    }
    else {
      m_y2AxisMenu.setEnabled(false);
    }
    
  }

  
  /**
   * Determine whether the graph type is dual Y
   *
   * @param graphType integer representing the graph type
   */
  private boolean _isDualY(int graphType) {
	  switch(graphType){
		  case Graph.AREA_VERT_STACK_SPLIT2Y:
		  case Graph.BAR_HORIZ_CLUST_2Y:
		  case Graph.BAR_HORIZ_CLUST_SPLIT2Y:
		  case Graph.BAR_HORIZ_STACK_2Y:
		  case Graph.BAR_HORIZ_STACK_SPLIT2Y:
		  case Graph.BAR_VERT_CLUST2Y:
		  case Graph.BAR_VERT_CLUST_SPLIT2Y:
		  case Graph.BAR_VERT_STACK2Y:
		  case Graph.BAR_VERT_STACK_SPLIT2Y:
		  case Graph.BUBBLE_2Y:
		  case Graph.LINE_VERT_ABS_2Y:
		  case Graph.LINE_VERT_ABS_SPLIT2Y:
		  case Graph.LINE_VERT_STACK_2Y:
		  case Graph.LINE_VERT_STACK_SPLIT2Y:
		  case Graph.SCATTER_2Y:
			  return true;
      default:
        break;
	  }
     return false;
  }

  /**
   * Determine whether the graph is Pie or Ring graph
   *
   * @param graphType integer representing the graph type
   */
  private boolean _isPie(int graphType) {
//    if(((graphType >= Graph.PIE) && (graphType <= Graph.RING_MULTI_PROP))
    if(((graphType >= Graph.PIE) && (graphType <= Graph.RING_MULTI))
        || ((graphType >= Graph.PIE_BAR) && (graphType <= Graph.RING_BAR)) ) {
  	  return true;
    }
    else {
      return false;
    }
  }

  /**
   * Determine whether the graph supports legend
   *
   * @param graphType integer representing the graph type
   */
  private boolean _isLegendSupported(int graphType) {
    switch(graphType) {
    case Graph.THREED_SURFACE :
    case Graph.STOCK_OHLC_CANDLE :
    case Graph.STOCK_OHLC_CANDLE_VOLUME:
      return false;
    default:
      break;
    }
    return true;
  }
  
  /**
   * create a default query given an instance of metadata manager
   */
  private Query _makeQuery(MetadataManager metadataManager) {
    Query query = null;
    try {
      query = m_frame.getQueryManager().createQuery();
      query.setMetadataMap(null, new MetadataMap(new String[]
                                   {MetadataMap.METADATA_VALUE,
                                    MetadataMap.METADATA_SHORTLABEL,
                                    MetadataMap.METADATA_LONGLABEL,
                                    MetadataMap.METADATA_DRILLSTATE,
                                    MetadataMap.METADATA_INDENT,
                                    MetadataMap.METADATA_RELHIERINFO}));
    }
    catch (Exception e) {
      m_frame.showExceptionDialog(this, e);
    }
    return (query);
  }
  

  /****************************************************************************
   * INNER CLASSES
   ***************************************************************************/
  /**
   * inner class to display format panels in a Dialog
   */
  class PanelDialog extends JDialog implements ActionListener  {

    // data member
    private JButton    applyButton;  // apply button
    private JButton    cancelButton; // cancel button
    private JPanel     panel;        // instance of JPanel
    // The extra room around the border
    private Border _sBorder = new EmptyBorder(6, 6, 8, 5);
    private Border _sBorderButtons = new EmptyBorder(8, 10, 0, 10);

    // constructor
    public PanelDialog(Frame parentFrame, String title, JPanel panel) { 
      super(parentFrame);
      setTitle(title);
      setModal(true);
      this.panel = panel;

      JComponent content = (JComponent) getContentPane();
      content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
      content.setBorder(_sBorder);
      content.setBackground(UIManager.getColor(oracle.bali.ewt.olaf
                                                     .ColorScheme.DARK_LOOK));

      GrayPane gp = new GrayPane(this.panel);
      content.add(gp);

      DialogButtonBar buttonPanel = new DialogButtonBar();
      buttonPanel.setBorder(_sBorderButtons);

      JPanel buttonPanel_east = new JPanel();

      // creating and adding apply button
      applyButton = new JButton("Apply");
      buttonPanel.add(applyButton, DialogButtonBar.CONSTRAINT_NULL);
      applyButton.addActionListener(this);
      getRootPane().setDefaultButton(applyButton);

      // creating and adding cancel button
      cancelButton = new JButton("Cancel");
      buttonPanel.add(cancelButton, DialogButtonBar.CONSTRAINT_FINISH);
      cancelButton.addActionListener(this);
      cancelButton.registerKeyboardAction(this,
                                 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
                                 JComponent.WHEN_IN_FOCUSED_WINDOW);
      getContentPane().add(buttonPanel);
      setResizable(false);
      pack();

    } 

    /**
     * implementing action listener
     *
     * @param e instance of ActionEvent
     */
    public void actionPerformed(ActionEvent e) {
      // if cancel button is pressed don't do anything
      // except closing the dialog
      if(e.getSource() == cancelButton) {
        setVisible(false);
        dispose();
        getParent().repaint();
      }
      // if apply button is pressed apply the changes to the graph
      // and close the dialog
      else if(e.getSource() == applyButton) {
        if(panel instanceof BasePanel) {
          ((BasePanel)panel).apply();
          if(panel instanceof GraphType) {
            _updateMenuBar(m_graph.getGraphType());
          }
        }
        else if( panel instanceof GraphLayout) {
          ((GraphLayout)panel).apply();
        }
        // update the toolbar
        if( m_graphToolBar != null ) {
          m_graphToolBar.update();
        }
        setVisible(false);
        dispose();
      }
    }
  } //PanelDialog


  /**
   * Since panels that can be added to query builder need to implement 
   * StandardPanel interface creating the default class that can be used by all
   * Graph format panels
   */
  private class StandardWizardPanel extends DefaultStandardPanel {

    // data members
    String m_panelId;  // panels id
    Image m_image;     // image for panel

    // constructor
    public StandardWizardPanel (String panelId) {
      super();

      m_panelId = panelId;
      m_image = ImageUtils.getImageResource (getClass(), "images/graph.gif");;
    }

    // returns the panel ID
    public String getId() {
      return m_panelId;
    }

    // returns the image assosiated with the panel
    public Image getImage() {
      return m_image;
    }

   // return the title for the panel
    public String getTitle() {
      return getId();
    }
  }  //StandardWizardPanel

}    //BIGraph