﻿ 

  /**
  Default constructor of TempestNS
  May 7, 2008: RB removed a semicolon after the final brace of the TempestNS() blank constructor. 
  This was an error, and I was hoping it would fix the IE problem, but apparently it did not. Still, better to fix it.
  **/
  function TempestNS()
  {

  }

  /**
  Every assembly attaches a caboose after it is written by the server
  The caboose consist of the call
  TempestNS.RegisterScript({assemblyKey})

  This call alerts the script register that the script is loaded
  which may in turn cause a callback function to be executed
  **/

  TempestNS.RegisterScript= function(assemblyKey)
  {
    if(!TempestNS.Client)return;
    if(!TempestNS.SCRIPTREGISTRY)
    {
      new TempestNS.Client.ScriptRegistry();
    }
    TempestNS.SCRIPTREGISTRY.AddAssembly(assemblyKey);
  };

  TempestNS.RequestAssembly= function(assemblyKey,callback)
  {
    if(!TempestNS.Client)return;
    if(!TempestNS.SCRIPTREGISTRY)
    {
    new TempestNS.Client.ScriptRegistry();
    }
    TempestNS.SCRIPTREGISTRY.RequestScript(assemblyKey,callback);
  };
  
 

  /**
  Common info about the Prospero Server, its build version, and dbg status
  **/
  TempestNS.Server = {
  'buildVersion' : '5667.142',
  'dbg' : '0',
  'domain' : 'discussions.consumerreports.org',
  'zone':'',
  'tempestPath':'/dir-script/644901/TempestNS.',
  'Apps': {
  'forum': '/n/pfx/forum.aspx',
  'blog': '/n/blogs/blog.aspx',
  'profile': '/n/pfx/profile.aspx',
  'album' :'/n/pfx/album.aspx',
  'wiki':'/n/pfx/wiki.aspx',
  'ideashare':'/n/pfx/ideashare.aspx',
  'control':'/n/pfx/control.aspx',
  'filerepository': '/n/pfx/filerepository.aspx'
  }
  };
  
 

/**
 <summary>
  Default constructor of TempestNS.Client
 </summary>
 <param name=""></param>
**/
TempestNS.Client = function()
{
 this.protocol = location.protocol; 
}

/**
 <summary>
  Method for resizing an image to its container so as to fit it in the same aspect ratio.
  It also centers the image horizontally and vertically.
  For an onload event handler, this function will work best if
   - Image is called WITHOUT width or height attributes (native dimensions will be calculated by browser)
   - Image style has been set to visibility: hidden
   - Container has a fixed width and height
   - Container is a block-level element with overflow set to hidden
 </summary>
 <param name="img">The image to be resized.</param>
 <param name="vertCenter">If true, image is centered vertically in container.</param>
 <param name="box">Optional. The container in which the image will be resized</param>
**/
TempestNS.Client.FitImageToContainer =  function (img, vertCenter, box)
{
  if (!img) return;
  var container = (box) ? box : img.parentNode;
  /* if (container.className != "myImage") return; */
  var imgW = img.width;
  var imgH = img.height;
  var conW = container.offsetWidth;
  var conH = container.offsetHeight;
  var imgAspect = imgW / imgH;
  var conAspect = conW / conH;
  var sizeCoefficient = 1;
  var marginTop = 0;
  if (imgAspect > conAspect) // resize horizontally
  {
    sizeCoefficient = conW / imgW;
    marginTop =  Math.floor( (conH - Math.floor(imgH*sizeCoefficient))/2);
  }
  else if (conAspect > imgAspect) // resize vertically
  {
    sizeCoefficient = conH / imgH;
  }
  img.style.width = Math.floor(imgW*sizeCoefficient) + "px";
  img.style.height = Math.floor(imgH*sizeCoefficient) + "px";
  //img.src = img.src + "?width=" + Math.floor(imgW*sizeCoefficient) + "&height=" + Math.floor(imgH*sizeCoefficient);
  if (vertCenter) img.style.marginTop = marginTop + "px";
  img.style.visibility = "visible";

};


/**
 <summary>
 Assumes the parent holds one avatar.
 - Find the parent
 - Find the prospero avatar
 - Resize it
 </summary>
 <param name=""></param>
**/
TempestNS.Client.FitImageToContainerById = function (boxId, vertCenter)
{
  var box = document.getElementById(boxId);
  if(!box) 
  {
    return;
  }
  var images = document.getElementsByTagName("img");
  for(var i = 0; i < images.length; i++)
  {
    if(images[i].className == "ptcImg")
    {
      TempestNS.Client.FitImageToContainer(images[i], vertCenter, box);
    }
  }
};


/**
 <summary>
  Cross-browser method for adding event listeners.
 </summary>
 <param name=""></param>
**/
TempestNS.Client.AddEventListener = function(elm, type, listener, useCapture) 
{
    if(document.addEventListener)
    {
        elm.addEventListener(type, listener, useCapture);
    }
    else if(document.attachEvent)
    {
        elm.attachEvent("on" + type, listener);
    }
    else
  {
        elm["on"+type] = callback;
    }
}


TempestNS.Client.StopPropogation=function(evt)
{
    if(evt==null)
    {
        evt = window.event;
    }
    if(evt.stopPropagation)
    {
        evt.stopPropagation();
        evt.preventDefault();
    }
    else if(evt.cancelBubble)
    {
        evt.cancelBubble=true;
        evt.returnValue = false;
    }
}

/**
 <summary>
  Remove a crossbrowser event listener to an element
 </summary>
**/
TempestNS.Client.RemoveEventListener = function(elm, type, listener, useCapture)
{
    if(document.removeEventListener)
    {
        elm.removeEventListener(type, listener, useCapture);
    }
    else if(document.detachEvent)
    {
        elm.detachEvent("on" + type, listener, useCapture);
    }
    else
  {
        elm["on"+type] = null;
    }
}



/**
 <summary>
  Helper function to determine if your browser prefers using the class or classname attribute
 </summary>
 <param name="elm">an element with a class attribute.  If it does NOT have a class then it will return "class".</param>
**/
TempestNS.Client.GetClassAttribute = function(elm)
{
  /* Needed to handle browser differences with JS and setting the class name.
     See if this browser uses pre IE8 model of assigning classes to elements */
  if(elm.getAttribute("className"))
  {
    return "className";
  }
  else
  {
    return "class";
  }
};



/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Client.GetControlValue = function(ctl)
{
  switch(ctl.type)
  {
    case "checkbox":
    {
      if(!ctl.checked)
      {
        return null;  /* nothing should be posted back */
      }
      break;
    }
    case "radio":
    {
      if(!ctl.checked)
      {
        return null;  /* nothing should be posted back */
      }
      break;
    }
    case "select-one":
    {
      return ctl.options[ctl.selectedIndex].value;
    }
  }
  return ctl.value;
}


/**
 <summary>
 Return the document height NOT the window height
 </summary>
**/
TempestNS.Client.GetDocumentHeight = function(theDoc)
{
  if(theDoc == null)
  {
    theDoc = document;
  }
  
  var h = Math.max(
    Math.max(
      Math.max(theDoc.body.scrollHeight, theDoc.documentElement.scrollHeight),
      Math.max(theDoc.body.offsetHeight, theDoc.documentElement.offsetHeight)
    ),
    Math.max(theDoc.body.clientHeight, theDoc.documentElement.clientHeight)
  );
  return h;
};


/**
 <summary>
  Returns the coordinates of an element relative to the page
 </summary>
 <param name=""></param>
**/
TempestNS.Client.GetElementPosition = function(elm)
{
  if(!elm){
    return {left:0, top:0, absTop:0};
  }
  var offsetTrail = elm;
  var offsetLeft = 0;
  var offsetTop = 0;
  while(offsetTrail) 
  {
    offsetLeft += offsetTrail.offsetLeft;
    offsetTop += offsetTrail.offsetTop;
    offsetTrail = offsetTrail.offsetParent;
  }
  if(navigator.userAgent.indexOf("Mac") != -1 && navigator.userAgent.indexOf("Safari") == -1 && typeof document.body.leftMargin != "undefined") 
  {
    offsetLeft += document.body.leftMargin;
    offsetTop += document.body.topMargin;
  }
  return {left:offsetLeft, top:offsetTop + elm.offsetHeight, absTop:offsetTop};
}


/**
 <summary>
  Returns the coordinates of an element relative to the page
 </summary>
 <param name=""></param>
**/
TempestNS.Client.GetMousePosition = function(e)
{
  var posx;
  var posy;
  if(e == null)
  {
    e = window.event;
  }
  if(e.pageX || e.pageY)
  {
    posx = e.pageX; 
    posy = e.pageY;
  }
  else if(e.clientX || e.clientY)
  {
    if(document.documentElement.scrollTop)
    {
      posx = e.clientX + document.documentElement.scrollLeft;
      posy = e.clientY + document.documentElement.scrollTop;
    }
    else
    {
      posx = e.clientX + document.body.scrollLeft;
      posy = e.clientY + document.body.scrollTop;
    }
  }
  return {"x":posx, "y":posy}
}


/**
 <summary>
  Returns the target of the mouse click
 </summary>
 <param name="e">Current window event</param>
**/
TempestNS.Client.GetMouseTarget = function(e) 
{
  var target;
  if(e == null)
  {
    e = window.event;
  }
  if(e.target) 
  {
    target = e.target;
  }
  else if(e.srcElement)
  {
    target = e.srcElement;
  }
  /* Correct for Safari bug */
  if(target.nodeType == 3)
  {
    target = target.parentNode;
  }
  return target;
}


/**
 <summary>
  Returns the height and width of the inner browser window
 </summary>
**/
TempestNS.Client.GetWindowSize = function() 
{
  var w = 0;
  var h = 0;
  if(typeof(window.innerWidth) == 'number') 
  {
    /* Non-IE */
    w = window.innerWidth;
    h = window.innerHeight;
  } 
  else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight )) 
  {
    /* IE 6+ */
    w = document.documentElement.clientWidth;
    h = document.documentElement.clientHeight;
  } 
  else if(document.body && (document.body.clientWidth || document.body.clientHeight )) 
  {
    /* IE 4 compatible */
    w = document.body.clientWidth;
    h = document.body.clientHeight;
  }
  return {"height":h, "width":w};
}


/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Client.IncludeScript = function(scriptUrl)
{
  /* Make sure the scriptURL is fully qualified */
  if(scriptUrl.substring(0,4) != "http")
  {
    if(scriptUrl.charAt(0) == "/")
    {
      scriptUrl = location.protocol+"//"+ TempestNS.Server.domain + scriptUrl;
    }
    if(scriptUrl.substring(0,3) == "../")
    {
      scriptUrl = location.protocol+"//"+ TempestNS.Server.domain + scriptUrl.substring(2,scriptUrl.length);
    }
  }
  var headElm = document.getElementsByTagName('head')[0];
  var scriptElm = document.createElement('script');
  scriptElm.setAttribute('type','text/javascript');
  scriptElm.setAttribute('src',scriptUrl);
  headElm.appendChild(scriptElm);
  return scriptElm;
}

TempestNS.Client.RemoveScript = function(scriptElm)
{
  var headElm = document.getElementsByTagName('head')[0];
  headElm.removeChild(scriptElm);
}




/**
 <summary>
  Scroll Page to a place on the customer's page
 </summary>
**/
TempestNS.Client.ScrollToId = function(scrollId)
{
  if(scrollId)
  {
    var placeOnPage = document.getElementById(scrollId);
    if(placeOnPage)
    {
      placeOnPage.scrollIntoView(true);
    }
  }
}


/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Client.ToolTip = function(parentDiv)
{
  /* Create outer <div/> */
    this.ptcToolTipBox = document.createElement("div");
    this.ptcToolTipBox.id = "ptcToolTip";
    this.ptcToolTipBox.style.position = "absolute";
    this.ptcToolTipBox.style.visibility = "hidden";
    this.ptcToolTipBox.className = "ptcToolTipBox";
    /* Create inner <div/> */
    this.ptcToolTipText = document.createElement("div");
    this.ptcToolTipText.style.position = "relative";
    this.ptcToolTipText.className = "ptcToolTipText";
    /* Add inner <div/> to the outer <div/> */
    this.ptcToolTipBox.appendChild(this.ptcToolTipText);
  /* Create an object to hold tips */
  this.msgs = new Array();
  
  /* Add Tool Tip Method */
  this.AddToolTip = function(tsn, msg)
  {
    this.msgs['msg'+tsn] = msg;
  }

    /* Hide Tool Tip Method */
  this.HideToolTip = function()
  {
    this.ptcToolTipBox.style.visibility = "hidden";
  }
  
  /* Show Tool Tip Method */
    this.ShowToolTip = function(tsn, e)
  {
    var mouse = TempestNS.Client.GetMousePosition(e);
    this.ptcToolTipText.innerHTML = this.msgs['msg'+tsn];
    this.ptcToolTipBox.style.top = mouse.y + 15 + "px";
    this.ptcToolTipBox.style.left = mouse.x + 15 + "px";
    this.ptcToolTipBox.style.visibility = "visible";
    if(parentDiv)
    {
      parentDiv.appendChild(this.ptcToolTipBox);
    }
    else
    {
      if(this.ptcToolTipBox.parentNode != document.body)
      {
        document.getElementsByTagName("body")[0].appendChild(this.ptcToolTipBox);
      }
    }
  }
}


TempestNS.Client.ToolTip.prototype = new Object();




/**
    needs server and client
    
    gopes in client

    the script provides utility methods for including new scripts dynamically
    the registry provides the ability to request new assemblys and the ability to execute callback functions once they 
    are complete
**/

TempestNS.Client.ScriptRegistry= function()
{
    if(TempestNS.SCRIPTREGISTRY)
    {
        return;
    }
    TempestNS.SCRIPTREGISTRY= this;
    this._Scripts = new Object();
    this._callbacks = new Object();
    this._head = null;
    this._Has = "";
};



/**
    This is executed from the call by the TempestNS.RegisterScript;
    Its key is inserted in the items collection 
    

**/



  
TempestNS.Client.ScriptRegistry.AddAssembly= function(assemblyKey)
{   
    if(this._Has!=""){
        this._Has+="|";
    }
    this._Has+=assemblyKey;    
    this._Scripts[assemblyKey]= assemblyKey;
    if(this._callbacks[assemblyKey])
    {
        var len = this._callbacks[assemblyKey].length;
        for(var index = 0 ; index <len;index++){
            this._callbacks[assemblyKey][index]();
        }
        if(TempestNS.COMPONENT_REGISTRY){
         TempestNS.COMPONENT_REGISTRY.LoadChildren();
        }
      
        this._callbacks[assemblyKey]=null;
    }
};
    
TempestNS.Client.ScriptRegistry.RequestScript = function(assemblyKey,callback)
{
  if(this._Scripts[assemblyKey])
  {
    callback();
  }
  else
  {
    if(this._callbacks[assemblyKey])
    {
        //there already hass been a request for this assembly -- just add to the call back array
        this._callbacks[assemblyKey].push(callback)
    }
    else
    {   this._callbacks[assemblyKey] = new Array();
        this._callbacks[assemblyKey].push(callback)
        this.MakeRequest(assemblyKey);
    }
  }      
};    
    
TempestNS.Client.ScriptRegistry.MakeRequest = function(assemblyKey)
{
    var src = location.protocol +"//" + TempestNS.Server.domain;
    src += TempestNS.Server.tempestPath;
    src += assemblyKey + ".js?";
     if(TempestNS.Server.dbg!='0')
     {
       src+="&dbg="+TempestNS.Server.dbg+"&";
       src+="ver=" + escape(new Date().valueOf())+"&";
     }
     src +=this.Has();  
     TempestNS.Client.IncludeScript(src);
};
    
TempestNS.Client.ScriptRegistry.Has= function()
{
    return "HaveScripts="+this._Has;
}    
    
    
TempestNS.Client.ScriptRegistry.prototype = new Object();
TempestNS.Client.ScriptRegistry.prototype.AddAssembly = TempestNS.Client.ScriptRegistry.AddAssembly;
TempestNS.Client.ScriptRegistry.prototype.RequestScript = TempestNS.Client.ScriptRegistry.RequestScript;
TempestNS.Client.ScriptRegistry.prototype.MakeRequest = TempestNS.Client.ScriptRegistry.MakeRequest;
TempestNS.Client.ScriptRegistry.prototype.Has = TempestNS.Client.ScriptRegistry.Has;





TempestNS.Client.StyleRegistry = function()
{
    /*insure its a singleton*/
    if(TempestNS.Client.STYLEREGISTRY){
        return;
    }
    TempestNS.Client.STYLEREGISTRY= this;
    this._styleSheets = new Object();
};

TempestNS.Client.StyleRegistry.AddStyle=function(href)
{
    
    if(!TempestNS.Client.STYLEREGISTRY){
        new TempestNS.Client.StyleRegistry();
    }
    
    key = escape(href);
    if(!TempestNS.Client.STYLEREGISTRY._styleSheets[key]){
      TempestNS.Client.STYLEREGISTRY._styleSheets[key]=href;
      if (document.createStyleSheet) /* IE only?  */
      {
        document.createStyleSheet(href);
      }
      else 
      {
        var ptCSS = document.createElement('link');
        ptCSS.rel = 'stylesheet';
        ptCSS.type = 'text/css';
        ptCSS.href = href;
        document.getElementsByTagName('head')[0].appendChild(ptCSS);
      }
    }
    
};

TempestNS.Client.StyleRegistry.prototype = new Object();



/**
 <summary>
  Hide or show all embedded objects on the page
 </summary>
 <param name=""></param>
**/
TempestNS.Client.EmbedShowHide = function(restore)
{
   objects = document.getElementsByTagName('embed');
   for (var i = 0; i < objects.length; i++) 
   { 
      objects[i].style.visibility = (restore ? 'visible' : 'hidden');
   }
};


/**
 <summary>
  Return the scroll top position
 </summary>
 <param name=""></param>
**/
TempestNS.Client.GetScrollTop = function()
{
  var ScrollTop = document.body.scrollTop;
  if(ScrollTop == 0)
  {
    if(window.pageYOffset)
    {
      ScrollTop = window.pageYOffset;
    }
    else
    {
      ScrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
    }
  }
  return ScrollTop;
};



 



/**
    <summary>
        A Crossbrowser event object used to inspect events with in event listeners
     <param name="evt">the the event If passed if null use window.event</param> 
        
    </summary>
**/    

TempestNS.Client.Event=function(evt)
{
    if(evt==null)
    {
        evt = window.event;
    }
    this._event = evt;
    if(this._event)
    {
       this._source = this._event.target; 
    }
    else
    {
        this._source = this._event.srcElement;        
    }
    if(this._event.pageX != null )
    {
        this._x= this._event.pageX;
        this._y = this._event.pageY;
    }
    else
    {
        this._x= this._event.clientX;
        this._y = this._event.clientY;      
    }
}

/** <summary>
        Cancels the bubble on an event
    </summary>
 **/

TempestNS.EventStopPropogation= function()
{
    if(this._event.stopPropagation)
    {
        this._event.stopPropagation();
        this._event.preventDefault();
    }
    else if(this._event.cancelBubble)
    {
        this._event.cancelBubble=true;
        this._event.returnValue = false;
    }
};

/**
 interface
**/    

 TempestNS.Client.Event.prototype.StopPropogation =  TempestNS.EventStopPropogation;

 
  

/**
 <summary>
  Submit Prospero Template Commands and manage results
 </summary>
 <param name=""></param>
**/
TempestNS.CommandHandler = function()
{
  /* If one already exists then use it */
  if(TempestNS.COMMANDHANDLER)
  {
    return;
  }
  /* Otherwise, create new global TempestNS.COMMANDHANDLER */
  TempestNS.COMMANDHANDLER = this;
  /* Create a object to hold in-process commands (their callbacks) */
  this.CommandCallbacks = new Object();
  this.nextCommandId = 1;
}

/**
 <summary>
 </summary>
 <param name="widgetId"></param>
 <param name="application"></param>
 <param name="cmd"></param>
 <param name="controlList"></param>
**/
TempestNS.CommandHandler.SendCommand = function(widgetId, application, webtag, cmd, form, controlList, callback)
{
  var src = "http://" + TempestNS.Server.domain;
  src += TempestNS.Server.Apps[application];
  src += "?webtag=" + webtag;
  src += (widgetId) ? "&widgetId="+ widgetId : "";
  src += "&nav=jsscommandhandler";
  src += "&dst="+escape(new Date().toString());
  if(TempestNS.Server.dbg)
  {
    src += "&dbg=" + TempestNS.Server.dbg;
  }
  
  if(callback)
  {
    this.CommandCallbacks[widgetId] = callback;
  }
  
  var postParams = "&ptButtonCmd=" + escape(cmd) + "&ptButtonValidate=false";
  
  // build up a regexp that matches the controls we want
  if(controlList && form)
  {
    var controlsToGet = "^" + controlList.replace(",", "$|^").replace("*", ".*") + "$";
    var controlsRE = new RegExp(controlsToGet, "i");
    for(var i = 0; i < form.elements.length; i++)
    {
      var el = form.elements[i];
      var elId = el.id;
      if(elId)
      {
        if(elId.search(controlsRE) != -1)
        {
          // this control is in our list
          var ctlVal = TempestNS.Client.GetControlValue(el);
          if(ctlVal != null)
          {
            postParams += "&" + el.name + "=" + escape(ctlVal);
          }
        }
      }
    }
  }
  else if(controlList)
  {
    for(var i = 0; i < controlList.length; i++)
    {
      for(var j = 0; j < controlList[i].length; j++)
      {
        var ctlVal = TempestNS.Client.GetControlValue(controlList[i][j]);
        if(ctlVal)
        {
          // var name = controlList[i][j].id.split("_");name[name.length - 1]
          postParams += "&" + controlList[i][j].name + "=" + escape(ctlVal);
        }
      }
    }
  }
  
  src += postParams;
      if(TempestNS.Server.dbg == '53')
  {
      alert(src);
   }
  TempestNS.Client.IncludeScript(src);  
}

TempestNS.CommandHandler.CommandComplete = function(widgetId, commandResult)
{
  var callback = this.CommandCallbacks[widgetId];
  if (callback)
    callback(commandResult);
}
/**
** An alias of the SetRelationship fucntion, specifying "ignore" as the relationship.
**/
TempestNS.CommandHandler.IgnoreUser = function(webtag, userId, callback)
{
  this.SetRelationship(webtag,userId,"ignore",callback);  
}
/**
** An alias of the SetRelationship fucntion, specifying "friend" as the relationship.
**/
TempestNS.CommandHandler.AddFriend = function(webtag, userId, callback)
{
  this.SetRelationship(webtag,userId,"friend",callback);   
}
/**
** An alias of the SetRelationship fucntion, specifying "neutral" as the relationship.
**/
TempestNS.CommandHandler.ResetRelationship = function(webtag, userId, callback)
{
  this.SetRelationship(webtag,userId,"neutral",callback);  
}
/**
**  Creates or updates a Roster Item
**  webtag - webtag of the forum which contains the user
**  userId - userId to act on
**  relationship - friend, ignore, neutral -- required to determine relationship value to set
**  callback - javascript function to call on completion
**/
TempestNS.CommandHandler.SetRelationship = function(webtag, userId, relationship, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'rosterSetRelationship(' + userId + ',' + relationship + ')';
    if(TempestNS.Server.dbg == '53')
  {
      alert(cmd);
   }
  this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);  
}
/**
**  Sets the rating on a message.
**  tid - message tid
**  tsn - message tsn
**  ratingValue - Integer (0-5) rating to set.
**/
TempestNS.CommandHandler.SetMessageRating = function(webtag, tid, tsn, ratingValue, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdSetMessageRating(' + tid + ',' + tsn + ',' + ratingValue + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);  
}

TempestNS.CommandHandler.AddFolder = function(webtag, formName, fldPrefix, ctlList, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdAddRepoFolder(' + fldPrefix + ')';
  this.SendCommand(cmdId, 'filerepository', webtag, cmd, formName, ctlList, callback);  
}

/**
**  Send an email message.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**/
TempestNS.CommandHandler.EmailSend = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdEmailSend(' + fieldPrefix + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}
/**
**  Delete a single message.
**  tid - tid of message
**  tsn - tsn of message to delete
**/
TempestNS.CommandHandler.MsgDelete = function(webtag, tid, tsn, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdMsgDelete(' + tid + ',' + tsn + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);
}
/**
**  Delete a message.
**  msg - The message to delete, formatted as tid.tsn
**/
TempestNS.CommandHandler.ApplyDelete = function(webtag, msg, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdApplyDelete(' + msg + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);  
}
/**
**  Sets the interest level on a discussion.
**  tid - tid of discussion to set interest level of.
**  newLevel - the interest level to set.  Integer 0, 1, or 2
**/
TempestNS.CommandHandler.SetInterestLevel = function(webtag, tid, newLevel, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'setInterestLevel('+ tid + ',' + newLevel + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);
}
/**
**  Mark all discussions older than the date specified as read.
**  newestDate - Discussions older than this will be treated as having been read.
**/
TempestNS.CommandHandler.MarkAsRead = function(webtag, newestDate, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdMarkAsRead(' + newestDate + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);
}
/**
**  Send a Terms-of-Service Violation Report
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**/
TempestNS.CommandHandler.SendTOSViolationReport = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdSendTOS(' + fieldPrefix + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}
/**
**  Send the current message by email to somebody else.  If no template name is specified in the parameters, then a standard format header is prepended to the body, and the template Forum.CCMessage is invoked.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  templateName - If a template name is specified as the second command argument, a templated email message is generated and sent.  This functionality is then identical to that provided by cmdEmailSend.  All
**  fields with the specified prefix are available in the template as params with the same names (without prefix, of course)
**  form - form that contains the fields that begin with the fieldPrefix
**/
TempestNS.CommandHandler.ForwardMessage = function(webtag, fieldPrefix, templateName, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = "";
  if(templateName != null) {cmd = 'cmdForward(' + fieldPrefix +',' + templateName + ')'; }
  else { cmd = 'cmdForward(' + fieldPrefix +')'; }
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}

TempestNS.CommandHandler.SetPresence = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdSetPresence(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}

/**
**  Casts a vote in a poll
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    choice - The number of the desired choice (1 thru 25). A choice of 0 means don't enter a vote. A choice of -1 means remove any previous vote.
**    tid - The tid of the poll discussion.
**/
TempestNS.CommandHandler.Vote = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdVote(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}

/**
**  Creates a new poll.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    allowVoteChanges - If true, then users may change their votes after casting them.
**    choice[n] - The text of the poll answers (choices). n can be from 1 to 25.
**    expiration - The number of days until the poll is closed. If -1, then it never closes.
**    folderId - The folderId of the folder where the poll should reside.
**    graphType - if 1 =&gt; vertical, else horiztonal.
**    sendAsHtml - If true, then the question and choices can contain HTML markup.
**    showResults - If true, then users may view the results of the poll before the poll closes.
**    subject - The subject of the poll, i.e. the poll question
**    toScreenName - The screenname of the addressee of the poll. Should be ALL.
**    tid - This is used when editing an existing poll
**/
TempestNS.CommandHandler.NewPoll = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommendId;
  this.nextCommandId++;
  var cmd = 'cmdNewPoll(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}

/**
**  Ends a current poll
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - The tid of the poll discussion to be deleted.
**/
TempestNS.CommandHandler.EndPoll = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdEndPoll(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

/**
**  Add a forum or forums to current user's list of favorites.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    for check boxes - id = [fieldprefix]_[forumId]  Any checked boxes will be added to list.
**    for list boxes - item values = [forumId]  Any selected items will be added to list.
**/
TempestNS.CommandHandler.SetMyForums = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdMyForumsSet(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
}

/**
**  Remove a forum or forums from current user's list of favorites.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    for check boxes - id = [fieldprefix]_[forumId]  Any checked boxes will be removed from list.
**    for list boxes - item values = [forumId]  Any selected items will be removed from list.
**/
TempestNS.CommandHandler.ResetMyForums = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdMyForumsReset(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

TempestNS.CommandHandler.SetRating = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdSetRating(' + fieldPrefix +')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

/**
**  Various commands to manage a discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  action - Action describing which manage command to execute.  Possible values: closediscussion, opendiscussion, deletediscussion, changesubject, movetofolder, movetowebtag,
**       prune, graft, transplant, setsticky
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be closed. (always required for each action)
**    various other fields, see specific commands from the action values for required fields.  All fields are required for each command unless otherwise specified.
**/
TempestNS.CommandHandler.ManageDiscussion = function(webtag, fieldPrefix, action, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdManageDiscussion('+ fieldPrefix + ',' + action + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

/**
**  Close a discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be closed.
**/
TempestNS.CommandHandler.CloseDiscussion = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "closediscussion", form, callback);
}

/**
**  Open a discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be opened.
**/
TempestNS.CommandHandler.OpenDiscussion = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "opendiscussion", form, callback);
}

/**
**  Delete a discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be deleted.
**/
TempestNS.CommandHandler.DeleteDiscussion = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "deletediscussion", form, callback);
}

/**
**  Change the subject of a discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to have it's subject changed.
**    newSubject - Text of the new subject (should contain no HTML, but will be stripped if there is)
**/
TempestNS.CommandHandler.ChangeSubject = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "changesubject", form, callback);
}

/**
**  Move a discussion or discussions to a new folder.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be moved to a new folder.
**    newFolderId - the folderId of the new folder the discussion(s) are being moved to.
**    discussions - a comma delimited list of tid(s) to move to specified folder.
**/
TempestNS.CommandHandler.MoveToFolder = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "movetofolder", form, callback);
}

/**
**  Move a discussion or all discussions to a new webtag.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be moved to a new webtag.
**    newWebtag - the new webtag to move discussion(s) to.
**    moveAllDiscussions - if true, all the discussions in the original folder will be moved to the new folder location. 
**    newWebtagFolderId - the new webtag's folder the discussion(s) are moving to.
**    linkOriginalDiscussion - if true, then the original discussion will contain a single message displaying a link to the new discussion location. 
**    If it is not checked, the original discussion will be deleted. 
**/
TempestNS.CommandHandler.MoveToWebtag = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "movetowebtag", form, callback);
}

/**
**  Prune a discussion - Remove a message from the discussion specified along with all of its replies and create a new discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be pruned.
**    newSubjectPrune - new subject of the discussion being created
**    tsnPrune - the tsn to start pruning from
**    newFolderIdPrune - the destination folder of the pruned discussion.
**/
TempestNS.CommandHandler.PruneDiscussion = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "prune", form, callback);
}

/**
**  Graft a discussion - Remove a message from the specified discussion along with all of its replies and insert it in another discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be grafted.
**    tsnGraft - the tsn (that has replies) to be inserted into another discussion.
**    destMsgGraft - In the form of tid.tsn.  This should be the message to which the message to be removed(tsnGraft) should be a reply.
**/
TempestNS.CommandHandler.GraftDiscussion = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "graft", form, callback);
}

/**
**  Transplant a discussion - Insert the entire discussion into another discussion.
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be transplanted.
**    destMsgTransplant - the tid.tsn to transplant disscussion to. This should be the message to which the first message of this discussion should be a reply.
**/
TempestNS.CommandHandler.TransplantDiscussion = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "transplant", form, callback);
}

/**
**  Set whether a discussion should contain sticky posts (always new or always unread).
**  fieldPrefix - All fields that are referenced by this command must have IDs comprised of this prefix, followed by an underscore, followed by the field name.
**  form - form that contains the fields that begin with the fieldPrefix
**  fields:  
**    tid - the tid of the discussion to be set sticky.
**    alwaysNew - boolean specifying whether or not to set this discussion as always new.
**    alwaysUnread - boolean specifying whether or not to set this discussion as always unread.
**/
TempestNS.CommandHandler.SetSticky = function(webtag, fieldPrefix, form, callback)
{
  this.ManageDiscussion(webtag, fieldPrefix, "setsticky", form, callback);
}

TempestNS.CommandHandler.Post = function(webtag, fieldPrefix, msgType, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd;
  if(msgType != null) { cmd = 'cmdPost('+ fieldPrefix + ',' + msgType + ')'; }
  else { cmd = 'cmdPost(' + fieldPrefix + ')'; }
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

TempestNS.CommandHandler.SetStatusInfo = function(webtag, fieldPrefix, tid, objectStatusId, comment, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  if(fieldPrefix != null)
  {
    var cmd = 'cmdSetStatusInfo(' + fieldPrefix + ')'; 
    this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback);
  }
  else
  {
    var cmd = 'cmdSetStatusInfo(' + tid + ',' + objectStatusId + ',' + comment + ')'; 
    this.SendCommand(cmdId, 'forum', webtag, cmd, null, null, callback);
  }
}

TempestNS.CommandHandler.ApplyDeleteByForm = function(webtag, fieldPrefix, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdApplyDelete('+ fieldPrefix + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

TempestNS.CommandHandler.ApplyEdit = function(webtag, fieldPrefix, msgType, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdApplyEdit('+ fieldPrefix + ',' + msgType + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

TempestNS.CommandHandler.MoveCategories = function(webtag, fieldPrefix, tid, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdMoveCategories('+ fieldPrefix + ',' + tid + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}


TempestNS.CommandHandler.MemberSet = function(webtag, fieldPrefix, userId, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdMemberSet('+ fieldPrefix + ',' + userId + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

TempestNS.CommandHandler.UploadFile = function(webtag, fieldPrefix, includeUrl, thumbMaxSize, form, callback)
{
  var cmdId = 'PCmd' + this.nextCommandId;
  this.nextCommandId++;
  var cmd = 'cmdUploadFile('+ fieldPrefix + ',' + includeUrl + ',' + thumbMaxSize + ')';
  this.SendCommand(cmdId, 'forum', webtag, cmd, form, fieldPrefix+'*', callback); 
}

TempestNS.CommandHandler.prototype.SendCommand                = TempestNS.CommandHandler.SendCommand;
TempestNS.CommandHandler.prototype.CommandComplete            = TempestNS.CommandHandler.CommandComplete;
TempestNS.CommandHandler.prototype.IgnoreUser                 = TempestNS.CommandHandler.IgnoreUser;
TempestNS.CommandHandler.prototype.AddFriend                  = TempestNS.CommandHandler.AddFriend;
TempestNS.CommandHandler.prototype.ResetRelationship          = TempestNS.CommandHandler.ResetRelationship;
TempestNS.CommandHandler.prototype.SetRelationship            = TempestNS.CommandHandler.SetRelationship;
TempestNS.CommandHandler.prototype.SetMessageRating           = TempestNS.CommandHandler.SetMessageRating;
TempestNS.CommandHandler.prototype.EmailSend                  = TempestNS.CommandHandler.EmailSend;
TempestNS.CommandHandler.prototype.MsgDelete          = TempestNS.CommandHandler.MsgDelete;
TempestNS.CommandHandler.prototype.ApplyDelete                = TempestNS.CommandHandler.ApplyDelete;
TempestNS.CommandHandler.prototype.SetInterestLevel           = TempestNS.CommandHandler.SetInterestLevel;
TempestNS.CommandHandler.prototype.MarkAsRead                 = TempestNS.CommandHandler.MarkAsRead;
TempestNS.CommandHandler.prototype.SendTOSViolationReport     = TempestNS.CommandHandler.SendTOSViolationReport;
TempestNS.CommandHandler.prototype.ForwardMessage             = TempestNS.CommandHandler.ForwardMessage;
TempestNS.CommandHandler.prototype.SetPresence          = TempestNS.CommandHandler.SetPresence;
TempestNS.CommandHandler.prototype.AddFolder                  = TempestNS.CommandHandler.AddFolder;
TempestNS.CommandHandler.prototype.Vote              = TempestNS.CommandHandler.Vote;
TempestNS.CommandHandler.prototype.NewPoll            = TempestNS.CommandHandler.NewPoll;
TempestNS.CommandHandler.prototype.EndPoll            = TempestNS.CommandHandler.EndPoll;
TempestNS.CommandHandler.prototype.SetMyForums          = TempestNS.CommandHandler.SetMyForums;
TempestNS.CommandHandler.prototype.ResetMyForums        = TempestNS.CommandHandler.ResetMyForums;
TempestNS.CommandHandler.prototype.SetRating          = TempestNS.CommandHandler.SetRating;
TempestNS.CommandHandler.prototype.ManageDiscussion        = TempestNS.CommandHandler.ManageDiscussion;
TempestNS.CommandHandler.prototype.CloseDiscussion        = TempestNS.CommandHandler.CloseDiscussion;
TempestNS.CommandHandler.prototype.OpenDiscussion        = TempestNS.CommandHandler.OpenDiscussion;
TempestNS.CommandHandler.prototype.DeleteDiscussion        = TempestNS.CommandHandler.DeleteDiscussion;
TempestNS.CommandHandler.prototype.ChangeSubject        = TempestNS.CommandHandler.ChangeSubject;
TempestNS.CommandHandler.prototype.MoveToFolder          = TempestNS.CommandHandler.MoveToFolder;
TempestNS.CommandHandler.prototype.MoveToWebtag          = TempestNS.CommandHandler.MoveToWebtag;
TempestNS.CommandHandler.prototype.PruneDiscussion        = TempestNS.CommandHandler.PruneDiscussion;
TempestNS.CommandHandler.prototype.GraftDiscussion        = TempestNS.CommandHandler.GraftDiscussion;
TempestNS.CommandHandler.prototype.TransplantDiscussion      = TempestNS.CommandHandler.TransplantDiscussion;
TempestNS.CommandHandler.prototype.SetSticky          = TempestNS.CommandHandler.SetSticky;
TempestNS.CommandHandler.prototype.Post                          = TempestNS.CommandHandler.Post;
TempestNS.CommandHandler.prototype.SetStatusInfo                 = TempestNS.CommandHandler.SetStatusInfo;
TempestNS.CommandHandler.prototype.ApplyDeleteByForm             = TempestNS.CommandHandler.ApplyDeleteByForm;
TempestNS.CommandHandler.prototype.ApplyEdit                     = TempestNS.CommandHandler.ApplyEdit;
TempestNS.CommandHandler.prototype.MoveCategories                = TempestNS.CommandHandler.MoveCategories;
TempestNS.CommandHandler.prototype.MemberSet                     = TempestNS.CommandHandler.MemberSet;
TempestNS.CommandHandler.prototype.UploadFile                    = TempestNS.CommandHandler.UploadFile;

new TempestNS.CommandHandler();


 TempestNS.DEBUG_WIN=null;TempestNS.Debug_Out=function(exception,object,funcName){if(!TempestNS.DEBUG_ON)return;if(TempestNS.DEBUG_WIN==null){TempestNS.DEBUG_WIN=document.createElement("div");TempestNS.DEBUG_WIN.style.position="absolute";TempestNS.DEBUG_WIN.style.top="0px";TempestNS.DEBUG_WIN.style.left="800px";TempestNS.DEBUG_WIN.style.width="400px";TempestNS.DEBUG_WIN.style.height="800px";TempestNS.DEBUG_WIN.style.overflow="auto";TempestNS.DEBUG_WIN.style.backgroundColor="white";document.body.appendChild(TempestNS.DEBUG_WIN);}var stemp="";if(funcName){stemp+="<strong>"+funcName+"</strong><br/>"}else{stemp+="<strong>error</strong><br/>";}for(s in exception){stemp+=s+":"+exception[s]+"<br/>";}stemp+="<br/><br/>";stemp+="<strong>object</strong><br/>";for(s in object){stemp+=s+":";if(typeof(object[s])!="function"){stemp+=object[s];}else{stemp+="function";}stemp+="<br/>";}stemp+="<br/><br/>";TempestNS.DEBUG_WIN.innerHTML=TempestNS.DEBUG_WIN.innerHTML+stemp;};



/**
    The component_common file containers common javascript objects that manage 
    component creation and registration
**/

/**
    <summary>
        Base Abstract class to derive new Registered Classes from
    </summary>
 **/
TempestNS.Registered_Component=function(){
    this._parentContainer = null;
    this._hasAlreadyBeenLoaded = false;
};

/**
 <summary>
 Implementation of the  register method of the  Registered_Component class  
  An instance of newObject can now register it self in the system by calling 
     this.register("A_NMTOKEN_DEFINED_FOR_NEWOBJECT");        
  If the object has no parent and
       this.register("A_NMTOKEN_DEFINED_FOR_NEWOBJECT",parent);        
 If it does.
 </summary>
 <param name="Control_Prefix">A NMTOKEN to define the Control (does not need to be unique except it helps with debugging if it is)</param>
 <param name="Parent"> A Parent Object that is derived from  Registered_Container</param>
**/

TempestNS.Registered_Component.Register=function (Control_Prefix,Parent)
{   
    if(!TempestNS.COMPONENT_REGISTRY)
    {
       new TempestNS.Component_Register();
    }
    this._refIndex =  Control_Prefix+ TempestNS.Registered_Component.count++;  
    this._parentContainer = Parent;
    this._control = Control_Prefix;
    if(Parent  && Parent._Components) 
    {
        this._ref= Parent._ref +"._Components['"+this._refIndex+"']";
        Parent._Components[this._refIndex]=this;
        this._Is_Registered = true;
        
    }
    else if(TempestNS.COMPONENT_REGISTRY)
    {
        this._ref="TempestNS.COMPONENT_REGISTRY._Components['"+this._refIndex+"']";
        TempestNS.COMPONENT_REGISTRY._Components[this._refIndex]= this;
        this._Is_Registered = true;
    }
};

/**
 <summary>
 Copies all properties and methods form another object to the object that extends registered component
 </summary>
<param name="object">The javascript object </param>
**/

TempestNS.Registered_Component.CopyProperties= function(object)
{
    for(var prop in object)
    { 
        this[prop]=object[prop];
    }
};


/**

 <summary>
    Raises an event which bubbles through the each parent container until one is listening 
 </summary>
 <param name="object">The javascript object </param>

**/

TempestNS.Registered_Component.RaiseEvent= function(eventName, jArg)
{
    if(this._eventListeners[eventName])
    {
        this._eventListeners[eventName](jArg);
    } 
    else
{
    if(this._parentContainer)
    {
        if(this._parentContainer.Listen)
        {
            this._parentContainer.Listen(eventName, jArg);
        }
        }
    }
};


TempestNS.Registered_Component.prototype.register          = TempestNS.Registered_Component.Register;
TempestNS.Registered_Component.prototype.OnLoad            = function(){};
TempestNS.Registered_Component.prototype.OnUnload          = function(){};
TempestNS.Registered_Component.prototype.OnResize          = function(){};
TempestNS.Registered_Component.prototype.CopyProperties    = TempestNS.Registered_Component.CopyProperties;
TempestNS.Registered_Component.prototype.RaiseEvent        = TempestNS.Registered_Component.RaiseEvent;

/**global count used to name components uniquely **/

TempestNS.Registered_Component.count = 0;

/** 
    <summary>
        Base Abstract class to derive new parent elements from  from
    </summary>
**/

TempestNS.Registered_Container=function(){
    TempestNS.Registered_Component.call(this);
    this._Components = new Object();
    this._eventListeners = new Object();
};

/**
 <summary>
  Unloads all the child components of a parent component
 </summary>
 **/
 
TempestNS.Registered_Container.UnloadChildren=function()
{
    for(var s in this._Components)
    {
      try
        {
            this._Components[s].OnUnload();
            this._Components[s]= null;
        }
        catch(exception)
        {
           TempestNS.Debug_Out(exception,this._Components[s],"Unload");
        }     
    } 
    this._Components = new Object();   
};

/**
  <summary>
      Loads all the child components of a parent component
  </summary>
**/ 
TempestNS.Registered_Container.LoadChildren=function()
{
    for(var s in this._Components)
    {
        try
        {
            this._Components[s].OnLoad();
        }
        catch(exception)
        {
            TempestNS.Debug_Out(exception,this._Components[s],"Load");
        }        
     }    
};

/**
<summary>
    resizes all the child components of a parent component
</summary>
**/
TempestNS.Registered_Container.ResizeChildren=function()
{
    for(var s in this._Components)
    {
        try
        {
            this._Components[s].OnResize();
        }
        catch(exception)
        {
            TempestNS.Debug_Out(exception,this._Components[s],"resize");
        }     
    } 
};

/**
 <summary>
    Calls a named Method on each Child passing in the specified args
 </summary>
 <param name="Method"> the name of the method to be called on the children </param>
 <param name="args"> an array of arguments to pass to the method </param>
**/
TempestNS.Registered_Container.CallChildren=function(Method,args)
{
    for(var s in this._Components)
    {
        try
        {
            if(typeof this._Components[s][Method] == 'function'){
               this._Components[s][Method](args);             
            }
        }
        catch(exception)
        {
            TempestNS.Debug_Out(exception,this._Components[s],"call " + Method );
        }     
    } 
};

/** 
<summary>
    Listens for events being bubbled up from subcomponents
</summary>
**/
 TempestNS.Registered_Container.Listen = function(eventName,jArgs)
 {
        if(this._eventListeners[eventName])
        {
            this._eventListeners[eventName](jArgs);
        } 
        else
        {
            this.RaiseEvent(eventName,jArgs);
        }
 };

/**
<summary>
    Add an event listener 
</summary>
**/
TempestNS.Registered_Container.AddEventListener = function(eventName,listener){
    this._eventListeners[eventName] = listener;
};

/**
<summary>
    Interface definition for Registered_Container
</summary>       
**/

TempestNS.Registered_Container.prototype                   = new TempestNS.Registered_Component();
TempestNS.Registered_Container.prototype.ResizeChildren    = TempestNS.Registered_Container.ResizeChildren;
TempestNS.Registered_Container.prototype.UnloadChildren    = TempestNS.Registered_Container.UnloadChildren;
TempestNS.Registered_Container.prototype.LoadChildren      = TempestNS.Registered_Container.LoadChildren;
TempestNS.Registered_Container.prototype.CallChildren      = TempestNS.Registered_Container.CallChildren;
TempestNS.Registered_Container.prototype.Listen            = TempestNS.Registered_Container.Listen;
TempestNS.Registered_Container.prototype.AddEventListener  = TempestNS.Registered_Container.AddEventListener;

/**
<summary>
    A master parent that serves as the default parent for all components register
    If a components is registered without a parent it registers itself with Component registery
    This object always creates a single object that is attached to the window object;
</summary>
**/
TempestNS.Component_Register = function()
{
	if(TempestNS.COMPONENT_REGISTRY)
	{
		return;
	}
	TempestNS.Registered_Container.call(this);
	TempestNS.COMPONENT_REGISTRY = this;
   
	var loader = function(){
		try
    {
      TempestNS.COMPONENT_REGISTRY.LoadChildren();
		  if(window.PTCOMPONENT_REGISTRY)
		  {
			  window.PTCOMPONENT_REGISTRY.LoadChildren();
		  }
    }
    catch(e)
    {
    
    }
	};
	
	var unloader = function(){
		try
    {
      TempestNS.COMPONENT_REGISTRY.UnloadChildren();
    }
    catch(e)
    {
    
    }
	};
	
	var resizer = function(){
		try
    {
      TempestNS.COMPONENT_REGISTRY.ResizeChildren();
    }
    catch(e)
    {
    
    }
	};
	
	if(window.RegisterOnLoad)
	{
    /* If within our hosted solution, add loader to load queue */
		RegisterOnLoad(loader);
    window.onunload = unloader;
    window.onresize = resizer;
	}
	else
	{
    /* If browser supports W3C Recommended event listener */
    if(document.addEventListener)
    {
      /* If Opera, and Safari, listen to OnReadyState */
      if(document.readyState) 
      {
        // Poll readyState every second to see the DOM is complete 
        var timerPollDom = setInterval(function(){
          if(document.readyState == "complete")
          {
            clearInterval(timerPollDom);
            loader();
          }
        }, 1000);
        /* document.addEventListener("onreadystatechange", loader, false);*/
      }
      /* Else Firefox, listen to DOMContentLoaded */
      else
      {
        document.addEventListener("DOMContentLoaded", loader, false);
      }
      window.addEventListener("unload", unloader, false);
      window.addEventListener("resize", resizer, false);
    }
    /* Else the browser supports IE event listener */
    else if(document.attachEvent) 
    {
      document.attachEvent("onreadystatechange", loader);
      window.attachEvent("onunload", unloader);
      window.attachEvent("onresize", resizer);
    }
    /* Else the browser is very old */
    else
    {
      window.onload = loader;
      window.onunload = unloader;
	    window.onresize = resizer;
    }
	}
};



/*
<summary>
    The interface for the Component_Register
<summary> 
*/

TempestNS.Component_Register.prototype = new TempestNS.Registered_Container();


 


/**
 <summary>
  Default constructor of TempestNS.Ajax
 </summary>
 <param name=""></param>
**/
TempestNS.Ajax = function(src, callback, callbackArgs)
{
	/* Create Request Object */
	this.xhr = this.GetXHR();
	this.xhrSrc = src;
	var self = this;
	this.xhr.onreadystatechange = function(){
		if(self.xhr.readyState == 4 && self.xhr.status == 200)
		{
			callback(self.xhr, callbackArgs);
		}
	};
}

/**
 <summary>
  Construct and return an XMLHttpRequest object, based on the browser's capabilities
 </summary>
 <param name=""></param>
**/
TempestNS.Ajax.GetXHR = function()
{
	if(window.XMLHttpRequest)
	{
		try
		{
			return new XMLHttpRequest();
		}
		catch(e)
		{
			return null;
		}
	}
	else if(window.ActiveXObject)
	{
		try
		{
			return new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e)
		{
			try 
			{
      		return new ActiveXObject("Microsoft.XMLHTTP");
    	} 
			catch(e)
			{
      		return null;
    	}
		}
	}
}


/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Ajax.Open = function(action)
{
	if(action == "post")
	{
		this.xhr.open("POST", this.xhrSrc, true);
		this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
	}
}

/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Ajax.Send = function(params)
{
	this.xhrParams = params;
	this.xhr.send(this.xhrParams);
}

TempestNS.Ajax.prototype 		= new Object();
TempestNS.Ajax.prototype.GetXHR = TempestNS.Ajax.GetXHR;
TempestNS.Ajax.prototype.Open 	= TempestNS.Ajax.Open;
TempestNS.Ajax.prototype.Send 	= TempestNS.Ajax.Send;


 


/**
 <summary>
  Default Constructor for TempestNS.WidgetManager Object
 </summary>
**/
TempestNS.WidgetManager = function()
{
  /* If one already exists then use it */
  if(TempestNS.WIDGETMANAGER)
  {
    return;
  }
  /* Otherwise, create new global TempestNS.WIDGETMANAGER */
  TempestNS.WIDGETMANAGER = this;
  /* Create a object to hold all the Widgets that TempestNS.WIDGETMANAGER is managing */
  this.Widgets = new Object();
  
  /* Count of widgets in TempestNS.WidgetMan */
  this.elementCount = 0;
  /* Flag to test if the DOM is ready */
  this.domComplete = false;
  /* Default time to display a message to a user */
  this.messageTime = 5000;
  /* Id of the DOM Poll for Safari and Opera */
  this.pollId = 0;
  /* If Safari and Opera, implement DOM Polling */
  if(document.addEventListener && document.readyState)
  {
    this.StartPolling();
  }
  /* Add listeners to window.document or window */
  this.Initialize();  
}


/**
 <summary>
  Determine if the request is coming from {0: External Domain, 1: Same Domain, 2: Same Host}
 </summary>
**/
TempestNS.WidgetManager.GetEnvironment = function()
{
  /* If from Same Host, return 2 */
  if(TempestNS.Server.domain == window.location.host)
  {
    return 2;
  }
  /* Otherwise, see if it is from the Same Domain */
  else 
  { 
    if(this.GetRootDomain(window.location.host) == this.GetRootDomain(TempestNS.Server.domain))
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
}


/**
 <summary>
  Given a hostString, return the root domain
 </summary>
**/
TempestNS.WidgetManager.GetRootDomain = function(hostString)
{
    var hostArray = hostString.split(".");
	  while(hostArray.length >2)
    {
				hostArray.shift();
    }
    return hostArray.join(".");
}


/**
 <summary>
  Add listeners to window.document or to the window itself.
  Once the DOM is ready, stop polling and run loadWidgets one last time.
 </summary>
**/
TempestNS.WidgetManager.Initialize = function()
{
  /* Fire the following function when the DOM is ready */
  var callBack = function(){
    /* If listening to OnReadyState */
    if(document.readyState) 
    {
      /* Only run the following when the DOM is ready */
      if(document.readyState == 'complete')
      {
        TempestNS.WIDGETMANAGER.domComplete = true; 
        TempestNS.WIDGETMANAGER.LoadWidgets();
      }
    }
    else 
    {
      TempestNS.WIDGETMANAGER.domComplete = true; 
      TempestNS.WIDGETMANAGER.LoadWidgets();
    }
  }
  
  /* If browser supports W3C Recommended event listener */
  if(document.addEventListener)
  {
    /* If Opera, and Safari, listen to OnReadyState */
    if(document.readyState) 
    {
      document.addEventListener("onreadystatechange", callBack, false);
    }
    /* Else Firefox, listen to DOMContentLoaded */
    else
    {
      document.addEventListener("DOMContentLoaded", callBack, false);
    }
  }
  /* Else the browser supports IE event listener */
  else if(document.attachEvent) 
  {
    /* Listen to OnReadyState */
    document.attachEvent("onreadystatechange", callBack);
  }
  /* Else widgets won't work on older browsers */
  else
  {
    /* window.onload = callBack; */
  }
}
  

/**
 <summary>
  Scan document for <paw:widget/> tags, and call their .Load() function
 </summary>
**/
TempestNS.WidgetManager.LoadWidgets = function()
{
  /* Scan for all widgets and kick off each */
  var elements = document.getElementsByTagName("paw:widget");
  for(var i = 0; i < elements.length; i++)
  {
    /* Create new Widget Object */
    var cModule = new TempestNS.Widget(elements[i]);
    /* If it doesn't exist */
    if(!this.Widgets[cModule.widgetId])
    {
      /* Add it to the Widget_Man Registry */
      this.Widgets[cModule.widgetId] = cModule;
      /* Increment count */
      this.elementCount++;
      /* Load Widget onto the page */
      cModule.Load();
    }
  }
  /* If the DOM is ready, stop DOM Polling */
  if(this.domComplete)
  {  
    this.StopPolling();
  }
}

/**
 <summary>
  Make a hard refresh of a widget in the WIDGETMANAGER collection 
 </summary>
**/
TempestNS.WidgetManager.ReloadWidget = function(widgetId)
{
  if(TempestNS.WIDGETMANAGER.Widgets[widgetId])
  {
    var argsSplit = TempestNS.Widget.ArgsSplitter(TempestNS.WIDGETMANAGER.Widgets[widgetId].args);
    var argsUpdated = TempestNS.Widget.ArgsUpdater(argsSplit, [{"name":"cdsn","value":TempestNS.Widget.GetSeq()}]);
    var argsCombined = TempestNS.Widget.ArgsBuilder(argsUpdated);      
    TempestNS.WIDGETMANAGER.Widgets[widgetId].Refresh({'args':argsCombined});
  }
}


/**
 <summary>
  Set the content to appear in the widget
 </summary>
 <param name="widgetId">Id of the widget in the Widget_Man</param>
 <param name="sContent">New HTML to replace old content</param>
**/
TempestNS.WidgetManager.SetContent = function(widgetId, sContent)
{
  if(this.Widgets[widgetId])
  {
    this.Widgets[widgetId].SetContent(sContent);
  }
}


/**
 <summary>
  Create a setInterval to run loadWidgets() every 1 second
 </summary>
**/
TempestNS.WidgetManager.StartPolling = function() 
{
  if(this.pollId) 
  {
    return;
  }
  this.pollId = setInterval(function(){ TempestNS.WIDGETMANAGER.LoadWidgets(); }, 1000);
}


/**
 <summary>
  Clear an interval that matches the pollId
 </summary>
**/
TempestNS.WidgetManager.StopPolling = function() 
{
  if(!this.pollId) 
  {
    return;
  }
  clearInterval(this.pollId);
  this.pollId = null;
}


/**
 <summary>
  Create a new src to pass to the widget's update function
 </summary>
 <param name="widgetId">Id of the widget in the Widget_Man</param>
 <param name="uri">Fully qualified URL of the new content</param>
 <param name="scrollId">Optional: Id of the element on the page to scroll to</param>
**/
TempestNS.WidgetManager.UpdateContent = function(widgetId, uri, scrollId)
{
  if(this.Widgets[widgetId])
  {
    this.Widgets[widgetId].UpdateContent(location.protocol +"//" + TempestNS.Server.domain + uri, scrollId);
  }
}


/**
 <summary>
 You can call this function to run a js function when clicking on a link.  
 Added for widget intergration into new platform.
 </summary>
 <param name="fn">The function to run.</param>
**/
TempestNS.WidgetManager.GoToURL = function(JSON)
{
  try
  {
    if(JSON.fn)
    {
      // First make sure we have a function
      var functionToRun;
      if(typeof JSON.fn == "string")
      {
        functionToRun = function(JSON){ eval(JSON.fn); };
      }
      else if(typeof JSON.fn == "function")
      {
        functionToRun = JSON.fn;
      }
      // Now run it
      functionToRun(JSON);
    }
    else if(JSON.url)
    {
      window.location = JSON.url;
    }
  }
  catch(e){}
}


TempestNS.WidgetManager.prototype           = new Object();
TempestNS.WidgetManager.prototype.GetEnvironment  = TempestNS.WidgetManager.GetEnvironment;
TempestNS.WidgetManager.prototype.GetRootDomain    = TempestNS.WidgetManager.GetRootDomain;
TempestNS.WidgetManager.prototype.GoToURL = TempestNS.WidgetManager.GoToURL;
TempestNS.WidgetManager.prototype.Initialize    = TempestNS.WidgetManager.Initialize;
TempestNS.WidgetManager.prototype.LoadWidgets     = TempestNS.WidgetManager.LoadWidgets;
TempestNS.WidgetManager.prototype.ReloadWidget     = TempestNS.WidgetManager.ReloadWidget;
TempestNS.WidgetManager.prototype.SetContent    = TempestNS.WidgetManager.SetContent;
TempestNS.WidgetManager.prototype.StartPolling     = TempestNS.WidgetManager.StartPolling;
TempestNS.WidgetManager.prototype.StopPolling     = TempestNS.WidgetManager.StopPolling
TempestNS.WidgetManager.prototype.UpdateContent   = TempestNS.WidgetManager.UpdateContent;

window.PT_WIDGET_MAN=null;



 


/**
 <summary>
  Create Widget Object
 </summary>
 <param name="Element">Pointer to the DOM element holding the widget or an html place holder if widget defined by def <paw:widget/></param>
 <param name="def">a jsonized collection of parameters representing the parameters on the widget</param>
**/
TempestNS.Widget = function(Element, def)
{
	/* Initialize this widget instance as a Registered Container */
	TempestNS.Registered_Container.call(this);
	this.register(TempestNS.Widget.Prefix);
	this.onWidgetRefresh = function(){};
	this.canvas = null;
	this.script = null;
	/* Set a flag to make sure only one request at a time is made to the server */
	this.callingProspero = false;
	this._def = def;
	this.element = Element;
	if(!this._def)
	{  
		this.DeriveParamsFromPawTag(Element);
	}
	else
	{
		this.DeriveParamsFromDef(def);
	}
}



/**
 <summary>
 
 </summary>
**/
TempestNS.Widget.ArgsValueFinder = function(find)
{
  
	if(this.args)
  {
    var arg = this.args.split(";");
	  for(var i = 0; i < arg.length; i++)
	  {
		  if(arg[i] != "")
		  {
			  var a = arg[i].split(":");
			  if(a[0].toLowerCase() == find.toLowerCase())
        { 
           return a[1];
        }
		  }
	  }
  }
	return null;
}




/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Widget.DeriveParamsFromPawTag = function()
{
	/* Get parameters passed from <paw:widget/> */
	/* Currently only webtag is mandatory */
	this.app = this.element.getAttribute("app");
	if(!this.app || this.app == "")
	{
		/* Current default is forum*/
		this.app = "forum"; 
	}
	this.args = this.element.getAttribute("args");
  this.config = this.element.getAttribute("config");
	this.plan = this.element.getAttribute("plan");
	this._includeCSS = this.element.getAttribute("includeCSS");
  if((!this._includeCSS || this._includeCSS == "") && (this.app == "forum" || this.app == "wiki"))
	{
		/* Current default is false*/
		this._includeCSS = "false"; 
	}
	/* If a unique id for a preload message is supplied by the customer, hide it when the widget content is loaded */
	if(this.element.getAttribute("preloadid"))
	{
		this.preloadId = this.element.getAttribute("preloadid");
	}
	/* Otherwise, pass id of old preloader for backwards compatability */
	else
	{
		this.preloadId = "ptcloading";
	}
	
	this._userId = this.element.getAttribute("userid");
	this._loginCode = this.element.getAttribute("loginCode");
	this._profileName= this.element.getAttribute("profileName");
	if(this.element.getAttribute("onWidgetRefresh"))
	{
		try
		{
			this.onWidgetRefresh = new Function(this.element.getAttribute("onWidgetRefresh"));
		}
		catch(e)
		{
			this.onWidgetRefresh = function(){};
		}
	}
	this.type = this.element.getAttribute("type");
	this.webtag = this.element.getAttribute("webtag");
   
	/* If a unique key is supplied by the customer, use it to create the widgetId */
	if(this.element.getAttribute("key"))
	{
		this.widgetId = TempestNS.Widget.Prefix + this.element.getAttribute("key");
	}
	/* Otherwise, use the elementCount of the Widget_Man Registry */
	else
	{
		this.widgetId = TempestNS.Widget.Prefix + TempestNS.WIDGETMANAGER.elementCount;
	}
   
  /* If PSync */
  var psync = this.ReadPSyncHint();
  if(psync)
  {
    /* Needed because seamless will set the querystring to lowercase and 
    change PTWidget to ptwidget causing the widget to not load (See SetContent) */
    this.widgetId = this.widgetId.toLowerCase();
  }
}


/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Widget.DeriveParamsFromDef = function(Def)
{
	/* Get parameters passed from <paw:widget/> */
	/* Currently only webtag is mandatory */
	this.app =  this._def.app;
	if(!this.app || this.app == "")
	{
		/* Current default is forum*/
		this.app = "forum"; 
	}
	this.args = this._def.args;
	this.config = this._def.config;
	this.plan = this._def.plan;
  this._includeCSS = this._def.includeCSS;
	/* If a unique id for a preload message is supplied by the customer, hide it when the widget content is loaded */
	this.preloadId = "ptcloading";
	this._userId = this._def.userid;
	this._loginCode = this._def.loginCode;
	this._profileName = this._def.profileName;
	if(this._def.onWidgetRefresh)
	{
		try
		{
			this.onWidgetRefresh = new Function(this._def.onWidgetRefresh);
		}
		catch(e)
		{
			this.onWidgetRefresh = function(){};
		}
	}
	this.type = this._def.type;
	this.webtag = this._def.webtag;
	if(this._def.widgetId)
	{
		this.widgetId = this._def.widgetId;
	}
	else
	{
		this.widgetId = TempestNS.Widget.Prefix + TempestNS.WIDGETMANAGER.elementCount;      
	}
	TempestNS.WIDGETMANAGER.Widgets[this.widgetId] = this;
	TempestNS.WIDGETMANAGER.elementCount++
	if(!this._def.preventLoad)
	{	  
		this.Load();
	}
}


/**
 <summary>
  Finds a cookie and returns its value
 </summary>
**/
TempestNS.Widget.GetCookieValue = function(name)
{
  var allcookies = document.cookie;
  var cIndex = name +"=";
  var pos = allcookies.indexOf(cIndex);
  
  if(pos != -1) 
  {
    var start = pos + cIndex.length;                       
    var end = allcookies.indexOf(";", start);  
    if(end == -1) 
    {
      end = allcookies.length;
    }
    var value = allcookies.substring(start, end);  
    value = decodeURIComponent(value);
    return value;
  }
  
  return null; 
}


/**

 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Widget.GetSeq = function()
{
	var seq = TempestNS.Widget.SeqCount++;
  var rand = Math.floor(Math.random()*997) + seq;
	return rand;
}


/**
 <summary>
  Create a new src to pass to the widget's update function
 </summary>
**/
TempestNS.Widget.Load = function()
{
	src = this.WidgetSource();
	/* Call widget's Update function */
	this.UpdateContent(src);
}


/**
 <summary>
  Add new <script> to the body of the document
 </summary>
**/
TempestNS.Widget.OnLoad = function()
{
	this.LoadChildren();
}


/**
 <summary>
  Add new <script> to the body of the document
 </summary>
**/
TempestNS.Widget.OnResize = function()
{
	this.ResizeChildren();
}



/**
 <summary>
  Add new <script> to the body of the document
 </summary>
**/
TempestNS.Widget.OnUnload = function()
{
	/* let the widget manager know this can be loaded again */
	this._hasAlreadyBeenLoaded = false;
	this.UnloadChildren();
}




/**
 <summary>
  Add logic to read the hint from the query string or a cookie
 </summary>
**/
TempestNS.Widget.ReadPSyncHint = function()
{
  var PSynchHint = this.GetCookieValue("PSyncHint");
  if(PSynchHint)
  {
    return PSynchHint;
  }
  else
  {
    return this.ArgsValueFinder("pSyncHint");
  }
}




/**
 <summary>
  Reload the widget with the last scriptSrc saved
 </summary>
 <param name=""></param>
**/
TempestNS.Widget.Refresh = function(args)
{
	/* 
		args objects must call before being passed as args
		TempestNS.Widget.IWidgetCommand.Implement(this,webtag,app,plan,config,args); 
	*/
	if(args)
	{
		if(args.app && (args.app !=""))
		{
			this.app = args.app;
		}
		if(args.webtag && (args.webtag !=""))
		{
			this.webtag = args.webtag;
		}
		if(args.args && (args.args !=""))
		{
			this.args = args.args;
		}
		if(args.config && (args.config !=""))
		{
			this.config = args.config;    
		}
		if(args.userId)
		{
			this._userId = args.userId;
		}
		if(args.loginCode)
		{
			this._loginCode = args.loginCode;
		}
		if(args.profileName)
		{
			this._profileName = args.profileName;
		}
		if(args.plan)
		{
			this.plan = args.plan;
		}
	}
	/*make sure all child are unloaded*/
	this.OnUnload();
	this.scriptSrc = this.WidgetSource();
	this.UpdateContent(this.scriptSrc);
}


/**
 <summary>
  
 </summary>
 <param name=""></param>
**/
TempestNS.Widget.SendCommand = function(application, cmd, controlList)
{
	var src = location.protocol +"//"+ TempestNS.Server.domain;
	src += TempestNS.Server.Apps[this.app];
	src += "?webtag=" + this.webtag;
	src += "&widgetId="+ this.widgetId;
	src += "&nav=jsscommand";
	if(this.plan && this.plan != "")
	{
		src += "&pttv=2"; 
	}
	src += "&cdsn=" + TempestNS.Widget.GetSeq();  /* cache-defeating sequence number */
	if(TempestNS.Server.dbg)
	{
		src += "&dbg=" + TempestNS.Server.dbg;
	}
	var postParams = "&ptButtonCmd=" + escape(cmd) + "&ptButtonValidate=false";
	var form = this.canvas;
	if(form)
	{
		// build up a regexp that matches the controls we want
		if(controlList)
		{
			var controlsToGet = "^" + controlList.replace(",", "$|^").replace("*", ".*") + "$";
			var controlsRE = new RegExp(controlsToGet, "i");
			for(var i = 0; i < form.elements.length; i++)
			{
				var el = form.elements[i];
				var elId = el.id;
				if(elId)
				{
					if(elId.search(controlsRE) != -1)
					{
						// this control is in our list
						var ctlVal = TempestNS.Client.GetControlValue(el);
						if(ctlVal != null)
						{
							postParams += "&" + el.name + "=" + escape(ctlVal);
						}
					}
				}
			}
		}
	}
	src += postParams;
	TempestNS.Client.IncludeScript(src);
}


/**
 <summary>
  Replace old content with new content returned from Prospero
 </summary>
**/
TempestNS.Widget.SetContent = function(sContent)
{
	/* If there is a <paw:widget/> or <div/> containing a widget */
	if(this.element)
	{
		/* Find its parent */
		var pawParent;
		if(this.element.parentNode)
		{
			pawParent = this.element.parentNode;
		}
		/* Once you have located its parent */
		if(pawParent)
		{
			/* If the <paw:widget/> has not been replaced */
			if(!this.canvas )
			{
				/* If the customer created a preload message, hide it */
				if(this.preloadId)
				{
					var preLoadingMessage = document.getElementById(this.preloadId);
					if(preLoadingMessage)
					{
						preLoadingMessage.style.display = "none";
					}
				}
				/* Create a new <div/> to hold widget content */
				this.canvas = document.createElement("div");
				if(this._def)
				{
					this.canvas.style.display="none";
				}
				/* Assign it a class and id */
				this.canvas.className = "ptcWidgetParent";
				this.canvas.id = this.widgetId;
				/* Replace <paw:widet/> node with the new <div/> */
				pawParent.replaceChild(this.canvas, this.element);
				/* Set this.element to the new <div/> */
				this.element = this.canvas;
			}
			/* Replace old content */
			this.canvas.innerHTML = sContent;
			/* Allow new calls to Prospero to occur by this widget */
			this.callingProspero = false;
			/* Activate or re-activate this widget and its children */
			this.OnLoad();
			this._hasAlreadyBeenLoaded = false;
			/* Move page to an elementId if one is supplied */
			TempestNS.Client.ScrollToId(this.scrollId);
			if(this.onWidgetRefresh)
			{
				this.onWidgetRefresh();
			}
		}
	}
	this.callingProspero = false;
}


/**
 <summary>
  Set error message and diplay it onscreen
 </summary>
 <param name="msg">the message to be displayed</param>
**/
TempestNS.Widget.SetError = function(msg)
{
    this.errorMessage = msg;
    alert(this.errorMessage);
}


/**
 <summary>
  Add new <script> to the body of the document
 </summary>
**/
TempestNS.Widget.UpdateContent = function(src, scrollId)
{
	/* If you haven't already appended the new script */
	if(this.callingProspero != true)
	{
		/* Make sure no other requests is made for this widget until the current one is finished */
		this.callingProspero = true;
		/* Remove previously used script */ 
		if(this.script)
		{
			TempestNS.Client.RemoveScript(this.script);
			this.script = null;
		}
		/* Save last src supplied */
		this.scriptSrc = src;  /* this is the raw script source (fully qualified, but without the cache-defeat) */ 
		/* add cache-defeating  */
		src += "&cdsn=" + TempestNS.Widget.GetSeq();
		this.script = TempestNS.Client.IncludeScript(src);
		/* Set Scroll Id */
		this.scrollId = scrollId;
	}
} 


/**
 <summary>
 </summary>
 <param name=""></param>
**/
TempestNS.Widget.WidgetSource = function()
{
	var src = location.protocol +"//"+ TempestNS.Server.domain;
	src += TempestNS.Server.Apps[this.app];
	src += "?webtag=" + this.webtag;
	src += "&widgetId="+ this.widgetId;
	/* If using T2V2 implementation */
	if(this.plan && this.plan != "")
	{
		src += "&pttv=2&nav=" + this.plan; 
	}
	else
	{
		src += "&nav=jsscontent";
	}
	if(this._userId)
	{
		src += "&userId=" + this._userId; 
	}
	if(this._loginCode)
	{
		src += "&loginCode=" + this._loginCode; 
	}
	if(this._profileName)
	{
		src += "&profileName=" + this._profileName; 
	}
	/* If args exists, append it to the src variable */
	if(this.args && this.args != "")
	{
		/* Remove any semicolons */
		this.args = this.args.replace(/\%3[Bb]/g,'%20');
    /* Replace any non-encoded pounds */
		this.args = this.args.replace(/\#/g,'%23');
    /* Remove any < or > */
    this.args = this.args.replace(/\%3[Cc]/g,'%20');
    this.args = this.args.replace(/\%3[Ee]/g,'%20');
    this.args = this.args.replace(/\</g,'%20');
    this.args = this.args.replace(/\>/g,'%20');
		src += "&args=" + this.args;
    /* Add PSync */
    var psync = this.ReadPSyncHint();
    if(psync)
    {
      src += "&PSync=" + psync;
    }
	}
	/* If config exists, append it to the src variable */
	if(this.config && this.config != "")
	{
		src += "&config=" + this.config;
	}
	/* If type exists, append it to the src variable */
	if(this.type && this.type != "")
	{
		src += "&type=" + this.type;
	}
  /* If includeCSS exists, append it to the src */
	if(this._includeCSS && this._includeCSS != "")
  {
	  src += "&includeCSS=" + this._includeCSS;
  }
	/* If the debug flag has been set, add it to the src */
	if(TempestNS.Server.dbg)
	{
		src += "&dbg=" + TempestNS.Server.dbg;
	}
	return src;
}




TempestNS.Widget.prototype 							= new TempestNS.Registered_Container();
TempestNS.Widget.prototype.ArgsValueFinder  = TempestNS.Widget.ArgsValueFinder;
TempestNS.Widget.prototype.DeriveParamsFromPawTag 	= TempestNS.Widget.DeriveParamsFromPawTag;
TempestNS.Widget.prototype.DeriveParamsFromDef 		= TempestNS.Widget.DeriveParamsFromDef;
TempestNS.Widget.prototype.GetCookieValue = TempestNS.Widget.GetCookieValue;
TempestNS.Widget.prototype.Load 					= TempestNS.Widget.Load;
TempestNS.Widget.prototype.OnLoad 					= TempestNS.Widget.OnLoad;
TempestNS.Widget.prototype.OnResize 					= TempestNS.Widget.OnResize;
TempestNS.Widget.prototype.OnUnload 				= TempestNS.Widget.OnUnload;
TempestNS.Widget.prototype.ReadPSyncHint					= TempestNS.Widget.ReadPSyncHint;
TempestNS.Widget.prototype.Refresh 					= TempestNS.Widget.Refresh;
TempestNS.Widget.prototype.SendCommand 				= TempestNS.Widget.SendCommand;
TempestNS.Widget.prototype.SetContent				= TempestNS.Widget.SetContent;
TempestNS.Widget.prototype.SetError 				= TempestNS.Widget.SetError;
TempestNS.Widget.prototype.UpdateContent 			= TempestNS.Widget.UpdateContent;
TempestNS.Widget.prototype.WidgetSource 			= TempestNS.Widget.WidgetSource;

TempestNS.Widget.Prefix = "PTWidget";
TempestNS.Widget.Rev = 1;
TempestNS.Widget.SeqCount = 0;




new TempestNS.WidgetManager();
TempestNS.WIDGETMANAGER.LoadWidgets();



 


    TempestNS.Accordion  = function (CanvasKey,WidgetId,singleEntry,headClassName,openClassName,closedClassName)
    {
       TempestNS.Registered_Container.call(this);
       this._canvasKey = CanvasKey;
       this._canvas = null;
       this._singleEntry = singleEntry;
       this._headClassName = (headClassName) ? headClassName : "ptcHead";
       this._openClassName = (openClassName) ? openClassName : "ptcPanelOpen";
       this._closedClassName = (closedClassName) ? closedClassName : "ptcPanelClosed";
       this._widgetId = WidgetId;
       this._widget = TempestNS.WIDGETMANAGER.Widgets[this._widgetId];
       this._panels = new Object();
       this.register("Accordion",this._widget);
       this._loaded= false;
       
    };

    TempestNS.Accordion.OnLoad= function()
    {
      if(this._loaded)return;
      this._canvas = document.getElementById(this._canvasKey);
      this._panels = new Object();
      this._loaded = true;
      this.AttachAccordionEvents();
      this.LoadChildren();
    };

    TempestNS.Accordion.OnUnload = function()
    {
    if(this._clickhandler && this._canvas){
       /**
       You attachit - you detact it
       **/
     //TempestNS.Client.RemoveEventListener(this._canvas,"click", this._clickhandler ,true); 
    }
      this.UnloadChildren();
      this._loaded = false;
    };
    
    
    TempestNS.Accordion.GetValidChildren = function(elm)
    {
      if (!elm.childNodes)
        return null;
      var ary = elm.childNodes;
      var validChildren = new Array();
      for (var i=0, imax=ary.length; i<imax; i++)
      {
        if (ary[i].nodeType == 1)
        {
          validChildren.push(ary[i]);
        }
      }
      return validChildren;
    };
    
    TempestNS.Accordion.TogglePanels = function(evt)
    {
      var panels = this._panels;
      var openClassName = this._openClassName;
      var closedClassName = this._closedClassName;
      var headClassName = this._headClassName;
      /* Updated for Monster Crunch project on 8/27/08
      var evtTarget = TempestNS.Client.GetMouseTarget(evt);
      if (evtTarget.className != headClassName) return;
      */
      var evtTarget = this.FindParent(evt, headClassName);
      if (evtTarget)
      {
        for (var panel in panels)
        {
          var canvas = panels[panel]._canvas;
          if (canvas == evtTarget.parentNode.parentNode)
          {
            panels[panel].Toggle(openClassName,closedClassName);
          }
          else
          {
             if (this._singleEntry)
                panels[panel]._canvas.className = closedClassName;
          }         
        }
      }
    }

    TempestNS.Accordion.AttachAccordionEvents = function()
    {
      if (!this._canvas)
        return;
      var panels = TempestNS.Accordion.GetValidChildren(this._canvas);
      
      for (var i=0, imax=panels.length; i<imax; i++)    
      {
        var panel = new TempestNS.Accordion.Panel(panels[i],this);
        this._panels[panel._refIndex] = panel;      
      }
  /**
    new pattern for assigning an event listener with this instance in context
    this method improves code debugging and is cleaner ;
  **/
  
    var _self= this;
    /** construct a private handler function using the  insuring _self contains a valid reference to the current obj instance**/
    this._clickhandler = function(evt){
       _self.TogglePanels(evt);
     }; 
     
 //  TempestNS.Client.AddEventListener(this._canvas,"click",   new Function( "evt",this._ref +".TogglePanels(evt)"),true);
     TempestNS.Client.AddEventListener(this._canvas,"click", this._clickhandler ,true);
    };
    
    
    /**
     <summary>
     </summary>
    **/
    TempestNS.Accordion.FindParent = function(evt, className)
    {
      var p = TempestNS.Client.GetMouseTarget(evt);
      while(p)
      {
        if(p.className == className)
        {
          return p;
        }
        p = p.parentNode;
      }
      return null;
    };
    

    TempestNS.Accordion.prototype                          =  new TempestNS.Registered_Container();
    TempestNS.Accordion.prototype.FindParent                         =  TempestNS.Accordion.FindParent;
    TempestNS.Accordion.prototype.OnLoad                   =  TempestNS.Accordion.OnLoad;
    TempestNS.Accordion.prototype.OnUnload                 =  TempestNS.Accordion.OnUnload;
    TempestNS.Accordion.prototype.TogglePanels             =  TempestNS.Accordion.TogglePanels;
    TempestNS.Accordion.prototype.AttachAccordionEvents    =  TempestNS.Accordion.AttachAccordionEvents;

    TempestNS.Accordion.Panel = function(canvas,parent)
    {
      TempestNS.Registered_Container.call(this);
      this.register("AccordionPanel",parent);
      this._canvas = canvas;
    };
    
    TempestNS.Accordion.Panel.OnLoad = function()
    {

    };
    
    TempestNS.Accordion.Panel.Toggle = function(openClassName,closedClassName)
    {
        var classes = this._canvas.className.split(" ");
        var newClassName = "";
        var len = classes.length;
        var classFound = false;

        for (var i = 0; i < len; i++) {
            if (classes[i] == openClassName) {
                classes[i] = closedClassName;
                classFound = true;
            } else if (classes[i] == closedClassName) {
                classes[i] = openClassName; 
                classFound = true;
            }
            newClassName += classes[i] + " ";
        }
        
        if (!classFound) {
            newClassName += closedClassName;
        }
       
        this._canvas.className = newClassName;
    }
    TempestNS.Accordion.Panel.prototype                    = new TempestNS.Registered_Container();
    TempestNS.Accordion.Panel.prototype.OnLoad             = TempestNS.Accordion.Panel.OnLoad;
    TempestNS.Accordion.Panel.prototype.Toggle             = TempestNS.Accordion.Panel.Toggle;
 
 TempestNS.RegisterScript('Core');TempestNS.RegisterScript('Server');TempestNS.RegisterScript('Client');TempestNS.RegisterScript('ClientEvents');TempestNS.RegisterScript('CommandHandler');TempestNS.RegisterScript('Debug');TempestNS.RegisterScript('RegisterComponents');TempestNS.RegisterScript('Ajax');TempestNS.RegisterScript('WidgetManager');TempestNS.RegisterScript('Widget');TempestNS.RegisterScript('Accordion');