/**
 *    Copyright 2006 - 2011 Opera Software ASA
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *
 **/


/**
 * This file was autogenerated by hob
 *
 * @fileoverview
 * This file contains the tag manager implementation. The tag manager
 * provides a method for associating an id and a callback. The callback
 * can optionally have arguments.
 *
 * There are two ways of getting a pointer to the singleton. Either
 * you can call
 *
 * var instance = new cls.TagManager()
 *
 * or you can call
 *
 * var instance = cls.TagManager.getInstance()
 *
 * The result will be the same. Calling new cls.TagManager() multiple times
 * will only result in a single instance being created
 */

window.cls || ( window.cls = {} );

/**
 * @constructor
 */
window.cls.TagManager = function()
{
  if(cls.TagManager.instance)
  {
    return cls.TagManager.instance;
  }
  cls.TagManager.instance = this;

  const
  OBJECT = 0,
  METHOD = 1,
  ARGS = 2;

  this._tags = [];

  // use tag with value 1 to explicitly ignore the response
  this._tags[1] = [null, function(status, message){}, []];

  /**
   * Helper that returns the first available tag slot.
   */
  this._get_empty_tag = function()
  {
    for(var i = 2; this._tags[i]; i++);
    return i;
  };


  /**
   * To set a tagged callback. Arguments are object, method, additional
   * arguments. The method will be called on the object with status and
   * message data as the first and second argument, followed by the
   * additional arguments.
   * @param {Object} obj the object on which the method will be called or null
   * @param {Function} method the callback function
   * @param {Array} args_list the arguments of this list will be added to
   *               status and message data
   * @return {Number} temporary unique tag
   */
  this.set_callback = function(obj, method, args_list)
  {
    var tag = this._get_empty_tag();
    this._tags[tag] = [obj,  method, args_list || []];
    return tag;
  };

  this.handle_message = function(tag, status, data)
  {
    var cb_obj = this._tags[tag];
    if (cb_obj)
    {
      cb_obj[METHOD].apply(cb_obj[OBJECT], [status, data].concat(cb_obj[ARGS]));
      this._tags[tag] = null;
      return true;
    }
    return false;
  };

};

/**
 * Static method for getting the global instance of the tag manager
 * class.
 */
window.cls.TagManager.getInstance = function() {
  return new window.cls.TagManager();
};