/* --------------------------------------------------------------------------*
 *              AjaxPlugin plugin                                              *
 * This plugin provides a base class for AjaxPlugins.                                   *
 *---------------------------------------------------------------------------*/

var gPluginInstance = 0;//We will give each plugin instance a unique number

//*--- Main ---*
var AjaxPlugin = Class.create({

  // this.debug is a js debug flag in app.ini file via index.php:
  debug: (typeof(gaDebug) != 'undefined' && gaDebug)? true : false,// Prefer this.debug to gaDebug?

  // Store this server path at the class level (i.e. not per-plugin-instance):
  plugins_server_path: null,
    
  initialize: function(container_element)
  {
    // If nec., find our plugins server path and set it at the class level: 
    if (AjaxPlugin.prototype.plugins_server_path == null)
    {
      var myJSPath = GA_UTIL.get_script_path('baseClass.js');
      AjaxPlugin.prototype.plugins_server_path = myJSPath.replace(/baseClass\/baseClass.js/,''); 
    }
    
    // Copy the path value to this plugin instance (for convenience):
    this.plugins_server_path = AjaxPlugin.prototype.plugins_server_path;
    
    // Set up a hash for session data:
    this.session_data = $H({});
    
    // Set up a hashes for event hook functions
    this._valid_events = $H({});
    this._event_handler_map = $H({});
    
    // Here's a unique string for every plugin instance
    this.instance_id = ''+gPluginInstance;
    gPluginInstance += 1;
  },
  
  set_session_data: function(session_data)
  {
    // TBD
  },
  
  // Log messages:
  logMsg: function(msg)
  {
    if (typeof(console) == 'object') console.log(msg);
  },
  // Log errors:
  logError: function(msg)
  {
    if (typeof(console) == 'object')
      console.error(msg);
    else {
      if (this.debug) { alert(msg); }
      else throw(msg);
    }
  },
  logEx: function(e)
  {
    var msg = e.name+": "+e.message;
    if (!Prototype.Browser.IE) {
      msg += ' on line '+e.lineNumber+' of '+e.fileName+"\n";
      if (this.debug) {
        msg += e.stack;
      }
    }
    this.logError(msg);
  },
  
  // This method sets the valid event names, to thwart typos: 
  register_event_names: function(event_names)
  {
    // Convert the array to a hash, so we can look up the names later:
    event_names.each(function(event_name){
        this._valid_events.set(event_name, true);
    }.bind(this));
  },
  
  // This method validates that an event name is in our list:
  _validate_event_name: function(event_name)
  {
    if (this._valid_events.size() && // If valid events have been set... 
       !this._valid_events.get(event_name)) // and this one is not among them:
    {
      throw event_name + " is an invalid event for this object."
    }
  },
  
  // This method allows event consumers to register their interest in an event: 
  set_event_hook: function(event_name, javascript_func)
  {
    // Ensure this event name is valid for this class:
    this._validate_event_name(event_name);
    
    // If we don't already have an array of handlers for this event, create one:
    if (this._event_handler_map.get(event_name) == null)
    {
      this._event_handler_map.set(event_name, new Array());
    }

    // Add this new event handler to our array of handlers:
    this._event_handler_map.get(event_name).push(javascript_func);  
  },// End of set_event_hook()
  
  // This method clears all event hooks for a given event name, or pass null
  // to clear all event hooks for the object.
  clear_event_hooks: function(event_name)
  {
    if (event_name != null) { // If they gave an event name, clear it only:
      this._event_handler_map.unset(event_name);
    }
    else { // If they gave no event name, clear all the object's hooks:
      this._event_handler_map = new Hash();
    }
  },
  
  // This method clears a specific event hook.  Note the function ptr must be
  // *exactly* the same one initially registered.
  // See bind gotcha at http://prototypejs.org/api/event/stopObserving
  clear_event_hook: function(event_name, javascript_func)
  {
    var hook_set = this._event_handler_map.get(event_name);
    if (hook_set == null) throw "error - baseClass clearing hook not set";
    hook_set.each(function(hook, index){ // Look through the hooks:
      if (hook == javascript_func) { // If this is the spec'd one:
        return hook_set.splice(index,1);// remove it
      }
    });
  },
  

  // This method allows event publishers to notify that an event has occurred:
  raise_event: function(event_name, parameter)
  {
    // Ensure this event name is valid for this class:
    this._validate_event_name(event_name);
    
    var function_ptrs = this._event_handler_map.get(event_name);
    if (function_ptrs != null)
    {
      // Call all of the registered functions, passing them the parameter:
      function_ptrs.each(function(function_ptr){
        try { // Use try-catch for each hook function:
          function_ptr(parameter);
        }
        catch(e) { // What to do with an exception if we catch it?
          this.logEx(e);
        }
      }.bind(this));
    }
  },// End of raise_event()
  
  // A method to retrieve a cookie:
  getCookieVal: function(cookie_name)
  {
    return GA_UTIL.getCookieVal(cookie_name);
  },
  
  // A method to retrieve a cookie:
  setCookieVal: function(cookie_name, value, time_qty, time_unit)
  {
    return GA_UTIL.setCookieVal(cookie_name, value, time_qty, time_unit);
  }

});// End of AjaxPlugins Base Class 

