/*
 * ZoomExecutor.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 modeling;

import java.util.ArrayList;
import java.lang.Math;
import java.text.DecimalFormat;


import oracle.dss.connection.client.Connection;

import oracle.dss.dataSource.client.QueryClient;

import oracle.dss.metadataManager.client.MetadataManager;
import oracle.dss.metadataManager.common.MDFolder;
import oracle.dss.metadataManager.common.MDMeasure;
import oracle.dss.metadataManager.common.MM;
import oracle.dss.graph.*;

import oracle.dss.selection.Selection;
import oracle.dss.selection.step.MemberStep;

import oracle.dss.util.DataAccess;
import oracle.dss.util.DataDirector;
import oracle.dss.util.DataMap;
import oracle.dss.util.MetadataMap;

/**
 * This class is used to execute the Graph zooming in the
 * Executive Insight demo
 */

public class ZoomExecutor extends Object {

  /////////////////////
  //
  // Constants and members
  //
  /////////////////////

    private static final double ZOOM_STEP = 0.75;
    public static final int ZOOM_OFF = 0;
    public static final int ZOOM_IN = 1;
    public static final int ZOOM_OUT = 2;

    private int m_currentZoomStatus = ZOOM_OFF;

    private DecimalFormat revenueFormatter = new DecimalFormat("###,###");
    private DecimalFormat marginFormatter = new DecimalFormat("###,###.##");    

    private double yQuadrant = 99999;
    private double xQuadrant = 99999;
    
    // Product dimension and hierarchy ID
    private static final String productID     = "MDM!D_CS_OLAP.SHAWPRODUCTS";
    private static final String hierarchyID   = "MDM!D_CS_OLAP.SHAWPRODUCTS.PRODUCTS";

    private int m_currentBubble = 0;
   
  /////////////////////
  //
  // Constructors
  //
  /////////////////////

  /**
   * Constructor for <code>ZoomExecutor</code>.
   *
   */
  public ZoomExecutor() {
    super();    
  }
  
  public void init(MetadataManager metadataManager)
  {
      setZoomStatus(ZOOM_OFF);
  }

  
  /////////////////////
  //
  // Public Methods
  //
  /////////////////////
  public void resetGraphAxis(Graph bubbleGraph) {
    
    setZoomStatus(ZOOM_OFF);
    
    bubbleGraph.getY1Axis().setAxisMaxAutoScaled(true);
    bubbleGraph.getY1Axis().setAxisMinAutoScaled(true);    
    bubbleGraph.getX1Axis().setAxisMaxAutoScaled(true);
    bubbleGraph.getX1Axis().setAxisMinAutoScaled(true);      

    //bubbleGraph.getQuadrantLine().setQuadrantLineValueX(0, xQuadrant);
    //bubbleGraph.getQuadrantLine().setQuadrantLineValueY(0, yQuadrant);
  } 

  public void setZoom(Graph bubbleGraph, int bubbleSlice) 
  {
    double xValue = 0;
    double yValue = 0;
    double xMax = 0;
    double xMin = 0;
    double yMax = 0;
    double yMin = 0;

    checkQuadrantAxis(bubbleGraph);
    
    try {
        DataAccess da = bubbleGraph.getModel().getDataAccess();
        yValue = ((Double)da.getValue(bubbleSlice, 2, DataMap.DATA_UNFORMATTED)).doubleValue();
        xValue = ((Double)da.getValue(bubbleSlice, 1, DataMap.DATA_UNFORMATTED)).doubleValue();
    }
    catch (Exception e) {
        System.out.println("Could not get the zoom values: " + e);
    }
    
    bubbleGraph.getY1Axis().setAxisMaxAutoScaled(false);
    bubbleGraph.getY1Axis().setAxisMinAutoScaled(false); 
    bubbleGraph.getX1Axis().setAxisMaxAutoScaled(false);
    bubbleGraph.getX1Axis().setAxisMinAutoScaled(false);   

    xMin = bubbleGraph.getX1Axis().getAxisMinValue();
    xMax = bubbleGraph.getX1Axis().getAxisMaxValue();
    yMin = bubbleGraph.getY1Axis().getAxisMinValue();
    yMax = bubbleGraph.getY1Axis().getAxisMaxValue();     

    switch (getCurrentZoom()) 
    {
       case ZOOM_IN:  // Zoom In        
          xMin = xValue - Math.min(((xValue - xMin)* ZOOM_STEP), ((xMax - xValue)* ZOOM_STEP));
          xMax = xValue + Math.min(((xValue - xMin)* ZOOM_STEP), ((xMax - xValue)* ZOOM_STEP));
          yMin = yValue - Math.min(((yValue - yMin)* ZOOM_STEP), ((yMax - yValue)* ZOOM_STEP));
          yMax = yValue + Math.min(((yValue - yMin)* ZOOM_STEP), ((yMax - yValue)* ZOOM_STEP));          
          break;
       case ZOOM_OUT:  // Zoom out
          xMin = xMin - Math.min(((xValue - xMin)* ZOOM_STEP), ((xMax - xValue)* ZOOM_STEP));
          xMax = xMax + Math.min(((xValue - xMin)* ZOOM_STEP), ((xMax - xValue)* ZOOM_STEP));
          yMin = yMin - Math.min(((yValue - yMin)* ZOOM_STEP), ((yMax - yValue)* ZOOM_STEP));
          yMax = yMax + Math.min(((yValue - yMin)* ZOOM_STEP), ((yMax - yValue)* ZOOM_STEP));          
          break;
    }

    if (getCurrentZoom() != ZOOM_OFF) 
    {
       try {
         bubbleGraph.getY1Axis().setAxisMaxValue(yMax);
       }
       catch (Exception e) {
          System.out.println("Could not set Y1 axis max value: " + e);
       }
       try {
         bubbleGraph.getY1Axis().setAxisMinValue(yMin);
       }
       catch (Exception e) {
         System.out.println("Could not set Y1 axis min value: " +  e);
       }
       try {
         bubbleGraph.getX1Axis().setAxisMaxValue(xMax);
       }
       catch (Exception e) {
         System.out.println("Could not set X1 axis max value: " + e);
       }
       try {
         bubbleGraph.getX1Axis().setAxisMinValue(xMin); 
       }
       catch (Exception e) {
          System.out.println("Could not set X1 axis min value: " + e);
       }   
    }
    
    setQuadrantAxis(bubbleGraph, xValue, xMin, xMax, yValue, yMin, yMax);
  }

  public int getCurrentZoom()
  {      
    return m_currentZoomStatus;
  }
   
  public String getZoomStatus(int m_mode)
  {      
    String m_zoomStatus = "false";
   
    if (m_mode == getCurrentZoom()) {
        m_zoomStatus = "true";
    }
    else{
        m_zoomStatus = "false";
    }
    
    return m_zoomStatus;
  }
   
    
  public void setZoomStatus(int zoomStatus) 
  {
    m_currentZoomStatus = zoomStatus;
  }
  
  public void setCurrentBubble(int bubble) 
  {
    m_currentBubble = bubble;
  }

  public String getSalesRevenue(Graph bubbleGraph) 
  {
    double yValue = 0;
    
    try {
        DataAccess da = bubbleGraph.getModel().getDataAccess();
        yValue = ((Double)da.getValue(m_currentBubble, 0, DataMap.DATA_UNFORMATTED)).doubleValue();
    }
    catch (Exception e) {
        System.out.println("Could not get the Sales Revenue: " + e);
    }

    String output = revenueFormatter.format(yValue);
    return output;
  }

  public String getSalesPercentChange(Graph bubbleGraph) 
  {
    double xValue = 0;

    try {
        DataAccess da = bubbleGraph.getModel().getDataAccess();
        xValue = ((Double)da.getValue(m_currentBubble, 1, DataMap.DATA_UNFORMATTED)).doubleValue();
    }
    catch (Exception e) {
        System.out.println("Could not get Sales % Change: " + e);
    }

    String output = revenueFormatter.format(xValue);
    return output;
  }

  public String getMargin(Graph bubbleGraph) 
  {
    double zValue = 0;

    try {
        DataAccess da = bubbleGraph.getModel().getDataAccess();
        zValue = ((Double)da.getValue(m_currentBubble, 2, DataMap.DATA_UNFORMATTED)).doubleValue();
    }
    catch (Exception e) {
        System.out.println("Could not get Margin: " + e);
    }

    String output = marginFormatter.format(zValue);
    return output;
  }

  public String getProductLabel(Graph forecastGraph)
  {
    String productLabel = "";
    
    try {
        DataAccess da = forecastGraph.getModel().getDataAccess();
        productLabel = (String)da.getMemberMetadata(DataDirector.PAGE_EDGE, 0, 0, MetadataMap.METADATA_LONGLABEL);
    }
    catch (Exception e) {
        System.out.println("Could not get the Product label: " + e);
    }

    return productLabel;
  }
  
  public void updateGraphProductSelection(Graph graph, String product)
  {
    if (product != null)
    {
      // Create the MemberStep to update the graph
      Selection prodSel = new Selection(productID);
      prodSel.setHierarchy(hierarchyID);
      MemberStep prodMS = new MemberStep(productID);
      prodMS.setHierarchy(hierarchyID);
      prodMS.addMember(product);
      prodSel.addStep(prodMS);
    
      try
      {
        // Change the Product selections to display the selected Product
        ((QueryClient)graph.getDataSource()).applySelection(prodSel);
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
    }
  }
   
  private void checkQuadrantAxis(Graph bubbleGraph) 
  {
    if (xQuadrant == 99999) {
       xQuadrant = (bubbleGraph.getX1Axis().getAxisMaxValue()- bubbleGraph.getX1Axis().getAxisMinValue())/2;
       yQuadrant = (bubbleGraph.getY1Axis().getAxisMaxValue()- bubbleGraph.getY1Axis().getAxisMinValue())/2;
    }
  }
  
  private void setQuadrantAxis(Graph bubbleGraph, double xAxisValue, double xAxisMin, double xAxisMax, double yAxisValue, double yAxisMin, double yAxisMax) 
  {
       if (xQuadrant >= xAxisValue) {
           if (xQuadrant >= xAxisMax) {
              bubbleGraph.getQuadrantLine().setQuadrantLineValueX(0, xAxisMax);
           }
           else {
              bubbleGraph.getQuadrantLine().setQuadrantLineValueX(0, xQuadrant);
          }
       }
       else 
       {
           if (xQuadrant >= xAxisMin) {
              bubbleGraph.getQuadrantLine().setQuadrantLineValueX(0, xQuadrant);
           }
           else {
              bubbleGraph.getQuadrantLine().setQuadrantLineValueX(0, xAxisMin);         
           }           
       }

       if (yQuadrant >= yAxisValue) {
           if (yQuadrant >= yAxisMax) {
             bubbleGraph.getQuadrantLine().setQuadrantLineValueY(0, yAxisMax);       
           }
           else {
             bubbleGraph.getQuadrantLine().setQuadrantLineValueY(0, yQuadrant);       
           }
       }
       else 
       {
           if (yQuadrant >= yAxisMin) {
               bubbleGraph.getQuadrantLine().setQuadrantLineValueY(0, yQuadrant);       
           }
           else {
              bubbleGraph.getQuadrantLine().setQuadrantLineValueY(0, yAxisMin);         
           }
       }
  }
}
        



