/*
 * NewPresentationWizard.java
 *
 * Copyright (c) 2003, Oracle Corporation. 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.analyzer;
import java.awt.Frame;

import oracle.bali.ewt.wizard.ImageWizardPage;
import oracle.bali.ewt.wizard.WizardEvent;
import oracle.bali.ewt.wizard.WizardListener;

import oracle.dss.crosstab.Crosstab;
import oracle.dss.dataSource.client.QueryManager;
import oracle.dss.dataSource.common.Query;
import oracle.dss.dataView.Dataview;
import oracle.dss.datautil.gui.panel.StandardPanel;
import oracle.dss.graph.Graph;
import oracle.dss.graph.gui.GraphLayout;
import oracle.dss.graph.gui.GraphType;
import oracle.dss.queryBuilder.QueryBuilder;
import oracle.dss.queryBuilder.QueryBuilderDialog;
import oracle.dss.util.LayoutContext;
import oracle.dss.util.gui.layout.CrosstabLayout;


/**
 * Wizard for creating a new crosstab or graph.
 * This wizard extends the QueryBuilder, adding a page for a user to 
 * select the type of presentation they want to create.
 * If the user chooses to create a graph, this wizard also adds a page
 * for a user to select a graph type.
 * <p>
 * This wizard uses JEWT wizard support.
 */
public class NewPresentationWizard extends QueryBuilder 
                                   implements WizardListener { 

  /**
   * Graph that is being created.
   */
  private Graph                 m_graph;
  /**
   * GraphType panel, which is added to the wizard if the user is creating
   * a graph.
   */
  private GraphTypeWizardPanel   m_graphTypePanel;
  /**
   * The GraphType user-interface panel that appears in m_graphTypePanel.
   */
  private GraphType             m_graphType;
  /**
   * The crosstab that is being created.
   */
  private Crosstab              m_crosstab;
  /**
   * The QueryManager for the application.
   */
  private QueryManager          m_queryManager;
  /**
   * The type of view that is being created, either
   * {@link #CROSSTAB} or {@link #GRAPH}.
   */
  private int                   m_viewType;
  /**
   * Presentation Type panel, which is added to the QueryBuilder.
   * This panel prompts a user to specify whether to create a table or 
   * a crosstab.
   */
  private PresentationTypePanel m_prezType;
  /**
   * Whether the GraphType panel is in the wizard.
   */
  private boolean               m_isGraphTypeVisible = false;
  /**
   * View type: Crosstab.
   */
  public static final int       CROSSTAB = 0;
  /**
   * View type: Graph.
   */
  public static final int       GRAPH = 1;
  /**
   * ID for the Graph Type panel: "GraphType".
   */
  public static final String    GRAPH_TYPE = "GraphType";
  /**
   * Title for the Graph Type panel: "Choose a Graph Type".
   */
  public static final String    GRAPH_TYPE_TITLE = "Choose a Graph Type";

  /**
   * Constructor.
   * {@link Analyzer#newPresentation} calls this constructor, passing the
   * Analyzer class as the frame.
   * 
   * @param f The parent frame for this wizard. 
   */
  public NewPresentationWizard(Frame f) {
    super(f);

    // Hide Welcome page by default
    setShowWelcomeNextTime(false);
  }

  /**
   * Runs the wizard.
   * This method customizes the QueryBuilder by adding a new panel, where
   * the user specifies whether to create a graph or a crosstab.
   * <p>
   * After adding the panel to the QueryBuilder, it calls super.run()
   * to run the QueryBuilder.
   * 
   * @return <code>true</code> if this wizard runs successfully,
   *         <code>false</code> if it does not.
   */
  public boolean run () {
    boolean retval = false;
    
    // Check if there is a query associated with the Wizard.
    // if not, try to create one.
    // if one can not be created, return null
    try {

      Query query = (Query) this.getQuery();

      if (query == null) {
        if (m_queryManager == null) {
          return retval;
        }
        query = m_queryManager.createQuery();
        setQuery(query);
      }

      // Do not use a default query.  The user will create a query from scratch
      query.setDefaultQuery(false);      

      // Specify that the QueryBuilder will run in Wizard mode
      // Then, make the Presentation Type panel the first page of the wizard
      setMode(QueryBuilder.WIZARD);
      initialize();

      m_prezType = new PresentationTypePanel(this);    
      this.addPanel((StandardPanel) m_prezType, QueryBuilder.ITEMS_PANEL_ID);

      // Listen to navigation events on the wizard        
      ((QueryBuilderDialog) this.getContainer()).getWizard().addWizardListener(this);

      // Run the QueryBuilder.  If the user clicked OK, then return true
      if (super.run())
        retval = true;

    }
    catch (Exception ex) {
      System.out.println(ex);
      
    }

    return retval;

  }

  /**
   * Gets the presentation that the wizard creates.
   *  
   * @return The presentation that the wizard creates, or null, if no
   *          presentation was created.
   */
  public Dataview getDataview() {
    if (getViewType() == GRAPH) 
      return (Dataview) m_graph;
    else if (getViewType() == CROSSTAB) 
      return (Dataview) m_crosstab;
    else return null;      
   
  }

  /**
   * Sets the QueryManager for this wizard.
   * This method also sets the MetadataManager on this wizard to be the
   * MetadataManager that the QueryManager uses.
   * <p>
   * The {@link Analyzer#newPresentation} method calls this method when
   * it instantiates the wizard.
   * It passes the QueryManager from the {@link AnalyzerConnection} to this method.
   * 
   * @param qm The QueryManager for this wizard.
   */
  public void setQueryManager(QueryManager qm) {
    // Set the metadatamanager based on the QueryManager
    m_queryManager = qm;
    setMetadataManager(m_queryManager.getMetadataManager());
  }

  /**
   * Gets the QueryManager for this wizard.
   * 
   * @return The QueryManager that this wizard uses.
   */
  public QueryManager getQueryManager() {
    return m_queryManager;
  }
  
  /**
   * Sets the type of view to create.
   * 
   * @param viewType A constant that represents the type of view to create.
   *        Valid constants are {@link #CROSSTAB} and {@link #GRAPH}.
   */
  public void setViewType(int viewType) {
    if (viewType != NewPresentationWizard.CROSSTAB && viewType != NewPresentationWizard.GRAPH) {
      return;
    }
    m_viewType = viewType;
  }
  
  /**
   * Gets the type of view that this wizard creates.
   * 
   * @return A constant that represents the type of view. Valid constants
   *         are {@link #CROSSTAB} and {@link #GRAPH}.
   */
  public int getViewType () {
    return m_viewType;
  }

  /**
   * Handles page changes.
   * This method processes the navigation through the wizard.  The QueryBuilder
   * is based on the JEWT wizard framework.
   * For more information, see the JEWT javadoc for
   * details on the wizard's methods and events.
   * <p>
   * If the user is creating a graph, then this method instantiates a graph and
   * sets a Query on it.
   * This method then adds a GraphType 
   * page to the wizard, before the layout panel.
   * It also then sets the layout panel to be a graph layout panel.
   * <p>
   * If the user is creating a crosstab, then this method instantiates a 
   * crosstab.
   * This method does not add any panels in this case.
   * It sets the layout panel to be a crosstab layout panel.
   * <p>
   * This method shows how to add a panel to the QueryBuilder, and how to
   * remove the panel if it is not necessary.
   * 
   * @param e Information about the user's interaction in the wizard.
   */
  public void wizardSelectionChanged(WizardEvent e) {

    // Look at the page that is being navigated to
    ImageWizardPage nextPage = (ImageWizardPage) e.getPage();
    if (nextPage == null) {
      return;
    }

    /*
     * Each QueryBuilder panel has a unique ID.  This enables us to know 
     * where the user is in the wizard
     */
    String nextID = ((StandardPanel) nextPage.getInteractiveArea()).getId();

    /* If the user is creating a graph, then create a graph type dialog - which 
       will appear after the Pick Items panel.  Also, create the graph
       layout panel 
    */
    if (nextID.equals(QueryBuilder.ITEMS_PANEL_ID) && getViewType()==GRAPH) {
      // If graph has never been initialized, then initialize it and set the 
      // wizard up so that there are graph panels
      if (m_graph == null) {
        // Create a graph
        m_graph = new Graph();
        m_graph.setPagingControlVisible(true);
        m_graph.setDataSource((Query) this.getQuery());

        m_graphType = new GraphType(m_graph);
        m_graphTypePanel = new GraphTypeWizardPanel(GRAPH_TYPE, GRAPH_TYPE_TITLE);
        m_graphTypePanel.add(m_graphType);
        m_isGraphTypeVisible = true;
        this.addPanel((StandardPanel) m_graphTypePanel, QueryBuilder.LAYOUT_PANEL_ID);        
        
      }
      /*
       * The wizard needs to handle when the user navigates backwards and forwards.
       * 
       * Case: User created a graph previously, changed to Crosstab, 
       * Changed back to graph 
       */
      if (!m_isGraphTypeVisible) {
        this.addPanel((StandardPanel) m_graphTypePanel, QueryBuilder.LAYOUT_PANEL_ID);
        m_isGraphTypeVisible = true;
      }      

    }  // nextID == ITEMSPanel and GRAPH
    else if (nextID.equals(QueryBuilder.ITEMS_PANEL_ID) && getViewType()==CROSSTAB) {
      // If crosstab has never been initialized, then initialize it 
      if (m_crosstab == null) {
        // Create a crosstab
        m_crosstab = new Crosstab();
        m_crosstab.setPagingControlVisible(true);
        m_crosstab.setDataSource((Query) this.getQuery());      
      }

      // Hide graph type panel if nec
      if (m_graphTypePanel != null) {
        removePanel(GRAPH_TYPE);
        m_isGraphTypeVisible = false;  
      }
    } 
    /*
     * Next panel is the Layout panel.  Use the Crosstab layout panel here
     */
    else if (nextID.equals(QueryBuilder.LAYOUT_PANEL_ID) && this.getViewType()==CROSSTAB) {
        CrosstabLayout crosstabLayout = new CrosstabLayout();
        crosstabLayout.setPagingControlAttributes(m_crosstab);
        crosstabLayout.setLayoutContext((LayoutContext) this.getQuery());        
        this.setViewLayoutPanel(crosstabLayout);
    }
    
    /*
     *  Next panel is the layout panel, but this time the user is creating a graph
     */ 
    else if (nextID.equals(QueryBuilder.LAYOUT_PANEL_ID) && this.getViewType()==GRAPH) {
        m_graphType.apply();
        // Set up the Graph Layout panel
        GraphLayout graphLayout = new GraphLayout();
        graphLayout.setGraph(m_graph);      
        graphLayout.setLayoutContext((LayoutContext) this.getQuery());       
        this.setViewLayoutPanel(graphLayout);

    }
  }

  /**
   * Null implementation for the WizardListener interface.
   */
  public void wizardApplyState(WizardEvent e) {}
  /**
   * Null implementation for the WizardListener interface.
   */
  public void wizardCanceled(WizardEvent e) {}

  /**
   * Handles the case where the user clicks the Finish button.
   * If the user is creating a graph, then this method sets the GraphType
   * property on the graph.
   * 
   * @param e Information about the user's interaction in the wizard.
   */
  public void wizardFinished(WizardEvent e) {
    if (getViewType() == GRAPH) 
      m_graphType.apply();
  }
  
}