/*
** Copyright (c) 2008, 2023, Oracle and/or its affiliates.
*/

/**
 * AdfDhtmlDvtGraphPeer a subclass of AdfDhtmlDvtImageViewPeer
 * @extends AdfDhtmlDvtImageViewPeer
 */

//BUG FIX #5951953: check if peer has already been registered with LAF before
//registering it again, to avoid assertion error
if (typeof AdfDhtmlDvtGraphPeer == 'undefined')
{
    AdfRichUIPeer.createPeerClass(AdfDhtmlDvtImageViewPeer, "AdfDhtmlDvtGraphPeer", false);
      
    AdfPage.PAGE.getLookAndFeel().registerPeerConstructor(
        "oracle.dss.adf.graph.Graph",
        "AdfDhtmlDvtGraphPeer");
}

AdfDhtmlDvtGraphPeer.POPUP_LAUNCH_CONTEXT = "popupLaunchContext";
    
//Start Peer class

AdfDhtmlDvtGraphPeer.InitSubclass = function()
{
  AdfObject.ensureClassInitialization(AdfDhtmlDvtGraphPeer); 
}

/**
 * Override to reset client-side state and create proxy compatible with 
 * old SVG API.  
 */
AdfDhtmlDvtGraphPeer.prototype.AddFlashTagToDom = function(component)
{
  AdfDhtmlDvtGraphPeer.superclass.AddFlashTagToDom(component);
  
  this.ResetClientState(component);
  
  //create the proxy object to provide the same client-side API for Flash
  //that we provided for SVG
  this.CreateFlashSvgProxy(component);
}

/**
 * Override to reset client-side state.  
 */
AdfDhtmlDvtGraphPeer.prototype.LoadFlashXml = function( component )
{
  AdfDhtmlDvtGraphPeer.superclass.LoadFlashXml(component);
  
  this.ResetClientState(component);
}

/**
 * Reset state on the client-side component.
 * 
 * @param component component associated with this peer
 */
AdfDhtmlDvtGraphPeer.prototype.ResetClientState = function(component)
{
  //reset mode
  component._mode = AdfDvtGraph.MODE_DEFAULT;
  //reset client-side time selector listeners
  component._timeSelListeners = null;
  component._bFlashTimeSelListenerAdded = false;
}

/**
 * Create the proxy object to provide the same client-side API for Flash
 * that we provided for SVG.
 * 
 * @param component client-side component
 */
AdfDhtmlDvtGraphPeer.prototype.CreateFlashSvgProxy = function(component)
{
  //name of the proxy object
  var objName = this.GetSvgProxyName(component);
  
  window[objName] = new Object();
  
  window[objName].BI_SVG_MODE_DEFAULT = AdfDvtGraph.MODE_DEFAULT;
  window[objName].BI_SVG_MODE_ZOOM = AdfDvtGraph.MODE_ZOOM;
  
  //BUG 34184877 - MAKE DVT COMPATIBLE WITH CSP STANDARDS
  window[objName].setMode =function anonymous(mode) 
  {
    return AdfPage.PAGE.findComponent( component.getClientId() ).setMode(mode);
  }
  
  //BUG 34184877 - MAKE DVT COMPATIBLE WITH CSP STANDARDS
  window[objName].addTimeSelectorListener = function anonymous(listener) 
  {
    return AdfPage.PAGE.findComponent( component.getClientId() ).addTimeSelectorListener(listener);
  }
  
  //BUG 34184877 - MAKE DVT COMPATIBLE WITH CSP STANDARDS
  window[objName].removeTimeSelectorListener = function anonymous(listener) 
  {
    return AdfPage.PAGE.findComponent( component.getClientId() ).removeTimeSelectorListener(listener);
  }
}

/**
 * Get the name of the SVG proxy object on the window.
 * 
 * @param component graph client-side component
 * 
 * @return SVG proxy object name
 */
AdfDhtmlDvtGraphPeer.prototype.GetSvgProxyName = function(component)
{
  //isolate the graph id from the client id
  var graphId = this.GetGraphIdFromClientId(component);
  //create the name of the proxy object
  var objName = graphId + '_svg';
  return objName;
}

/**
 * Get the graph id from the client id.
 * 
 * @param component graph client-side component
 * 
 * @return graph id
 */
AdfDhtmlDvtGraphPeer.prototype.GetGraphIdFromClientId = function(component)
{
  //isolate the graph id from the client id
  var graphId = new String(component.getClientId());
  if (graphId)
  {
    if (graphId.length > 0)
    {
      var i = graphId.lastIndexOf(':');
      if (i > -1 && i < graphId.length - 1)
        graphId = graphId.substring(i + 1, graphId.length);
    }
  }
  return graphId;
}

/**
 * Notify the client-side time selector listeners of an event.
 * 
 * @param startTime long start time of time selector
 * @param endTime long end time of time selector
 */
AdfDhtmlDvtGraphPeer.prototype.NotifyTimeSelectorListeners = function(startTime, endTime)
{
  var component = this.getComponent();
  var src = component.getClientId();
  var listeners = component._timeSelListeners;
  
  //local variables 'src', 'startTime', and 'endTime' must be defined before
  //evaluating the listener string
  for (var i = listeners.length - 1; i >= 0; i--)
    eval(listeners[i]);
}

/**
 * Determine if the time selector listener string specifies its own
 * arguments (src, startTime, endTime).  
 * 
 * @param listener time selector listener string
 * 
 * @return true if the listener specifies its arguments, false if not
 */
AdfDhtmlDvtGraphPeer.prototype.TimeSelListenerHasArgs = function(listener)
{
  var indexA = listener.lastIndexOf('(');
  if (indexA > -1)
  {
    var indexB = listener.indexOf(')', indexA);
    if (indexB > indexA)
    {
      var indexSrc = listener.indexOf('src', indexA);
      if (indexSrc > indexA && indexSrc < indexB)
      {
        var indexStartTime = listener.indexOf('startTime', indexSrc);
        if (indexStartTime > indexSrc && indexStartTime < indexB)
        {
          var indexEndTime = listener.indexOf('endTime', indexStartTime);
          if (indexEndTime > indexStartTime && indexEndTime < indexB)
          {
            return true;
          }
        }
      }
    }
  }
  
  return false;
}

AdfDhtmlDvtGraphPeer.prototype.showPopupHelper = function(context)
{
  this.ForceSetPropertyChange(AdfDhtmlDvtGraphPeer.POPUP_LAUNCH_CONTEXT, context, false, 
                              AdfUIComponent.PROPAGATE_ALWAYS);
}

/**
 * @export
 * Returns an optional context object for the drag.  This context object is packed into
 * the transferable and sent as part of the drop event.  This function is always called
 * after getDragTransferable.
 */
AdfDhtmlDvtGraphPeer.prototype.getDragContext = function(inputEvent) {
  // Find the component mouse position
  var mousePos = this._getComponentCoords(this.getComponent(), inputEvent);

  if (this.getComponent().getClientImageFormat()=="HTML5") {
      if (this._view && this._view.getDragContext) {
        var context = this._view.getDragContext(mousePos.x, mousePos.y);
        return new AdfDvtGraphDragContext(context.xValue, context.yValue);
      }
      else {
        return null;
      }
  }
  
  // Call Flash for drag availability
  var movieObj = this.getFlashMovieObj();
  if(movieObj && movieObj['getDragContext']) {
    var dragContext = movieObj['getDragContext'](mousePos.x, mousePos.y);
    return new AdfDvtGraphDragContext(dragContext.xValue, dragContext.yValue);
  }
    
  // If not implemented in Flash, return null
  return null;
}

/**
 * Returns the data for a drag and drop operation within this component.
 */
AdfDhtmlDvtGraphPeer.prototype.getDragData = function() {
  // This function is used to pass the data up to the server for graph
  // markers.  We should remove it when we stop firing the DropEvent
  // on the server. TODO
  if (this.getComponent().getClientImageFormat()=="HTML5") {
      if (this._view && this._view.getDragData) {
          return this._view.getDragData();
      }
  }
  else {
      var movieObj = this.getFlashMovieObj();
      if(movieObj && movieObj['getDragData'])
        return movieObj['getDragData']();
  }
  return null;
}

AdfDhtmlDvtGraphPeer.prototype.getAccessibleName = function() {
  return this.getComponent().getShortDesc();
}

/**
 * Returns the drag recognizer that is used by the drag source to determine
 * whether a drag is started.
 */
AdfDhtmlDvtGraphPeer.prototype.getDefaultDragRecognizer = function(component)
{
  // This drag recognizer can deal with the pan zoom canvas.  It calls into
  // the peer to figure out what to do.
  return new AdfDvtDragRecognizer();
}



AdfDhtmlDvtGraphPeer.prototype.LoadHTML5Content = function(component){
  AdfDhtmlDvtGraphPeer.superclass.LoadHTML5Content.call(this, component);
  if (component.getMode() != null) {
      component.setMode(component.getMode());
  }
}

/**
 * @override
 */
AdfDhtmlDvtGraphPeer.prototype.useDragGhostStyleClass = function() {
  // Want to keep the old Graph behavior, which is fully opaque drag feedback
  return false;
};
