/*[[
JJNode - a suite of components that provide client-side facilities for web applications.  Created by John Jameson
Copyright (C) 2007 - 2008 Unity In Work Ltd.  All Rights Reserved.
* @author   John Jameson
* @access   public
* @version: 0.91
* @date:    17 Jul 2008
This file is part of JJNode.
 
    JJNode is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    JJNode is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with JJNode.  If not, see <http://www.gnu.org/licenses/>.
]]*/
function JJError(e)
{
   if (e instanceof Error)
   {
      this.message = e.message;
   }
   else
   {
      this.message = e;
   }
   
   if (JJError.aMessages[this.message] === undefined)
   {
      alert('JJError: ' + this.message);
      JJError.aMessages[this.message] = true;
   }
   
}
JJError.prototype = new Error();
JJError.aMessages = [];
JJError.DOM_NOT_SUPPORTED = 'JJE001';
JJError.INVALID_SERVER_CONTENT = 'JJE002';
function JJNode(el)
{
   try
   {
      this.initialise();
      if (el)
      {
         this.initElement(el);
      }
   }
   catch (e)
   {
      throw new JJError('JJNode: ' + e);
   }
}
JJNode.className = 'JJNode';
JJNode.aNodes = [];
JJNode.iId = 0;
JJNode.register = function(jjN)
{
   try
   {
      if (!jjN.element.id)
      {
         jjN.element.id = 'JJNode' + JJNode.iId;
         JJNode.iId++;
      }
      else if (JJNode.aNodes[jjN.element.id])
      {
         throw new JJError('JJNode: element.id is not unique: ' + jjN.element.id);
      }
      else
      {
         JJNode.aNodes[jjN.element.id] = jjN;
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::register ' + e);
   }
};
JJNode.removeElementChildren = function(node)
{
   try
   {
      if (node.hasChildNodes())
      {
         while (node.lastChild)
         {
            node.removeChild(node.lastChild);
         }
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::removeElementChildren ' + e);
   }
};
JJNode.replaceElementClassName = function(el,strOld,strNew)
{
   try
   {
      if (!el.className)
      {
         el.className = strNew;
      }
      else
      {
         var aParts = el.className.split(' ');
         for (var c in aParts)
         {
            if (aParts[c] == strOld)
            {
               aParts[c] = undefined;
            }
            else if (aParts[c] == strNew)
            {
               aParts[c] = undefined;
            }
         }
         aParts.push(strNew);
         el.className = aParts.join(' ');
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::replaceElementClassName ' + e);
   }
};
JJNode.elementHasClassName = function(el,strClass)
{
   var bResult = false;
   try
   {
      if (el && el.className && el.className.search(strClass) != -1)
      {
         bResult = true;
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::elementHasClassName ' + e);
   }
   return bResult;
};
JJNode.removeNode = function(jjN)
{
   if (jjN)
   {
      jjN.removeChildren();
      if (jjN.element.parentNode)
      {
         jjN.element.parentNode.removeChild(jjN.element);
      }
   }
   return null;
};
JJNode.getElComputedStyle = function(el)
{
   var cs = null;
   if (document.defaultView && document.defaultView.getComputedStyle)
   {
      cs = document.defaultView.getComputedStyle(el,null);
   }
   else if (el.currentStyle)
   {
      cs = el.currentStyle;
   }
   return cs;
};
   
JJNode.prototype.initialise = function()
{
   this.xmlHttpRequestUrl = false;
   this.xmlHttpRequestMethod = 'POST';
   this.xmlHttpRequest = false;
   this.aUpdateActions = [];
   this.aErrorActions = [];
};
JJNode.prototype.initElement = function(el)
{
   this.element = el;
   el.jjNode = this;
   el.aEventHandlers = [];
   JJNode.register(this);
};
JJNode.prototype.id = function()
{
   return this.element.id;
};
JJNode.prototype.addEventAction = function(eventType,func)
{
   try
   {
      if (!this.element.aEventHandlers[eventType])
      {
         this.element.aEventHandlers[eventType] = [];
      }
      this.element.aEventHandlers[eventType].push(func);
   }
   catch (e)
   {
      throw new JJError('JJNode::addEventAction ' + e);
   }
};
JJNode.prototype.replaceClassName = function(strOld,strNew)
{
   JJNode.replaceElementClassName(this.element,strOld,strNew);
};
JJNode.prototype.initServerRequest = function(href,aParams,method)
{
   var url = href;
   if (aParams instanceof Array)
   {
      url += '?' + aParams.join('&');
   }
   this.xmlHttpRequestUrl = url;
   this.xmlHttpRequestMethod = method;
};
JJNode.prototype.sendServerRequest = function(href,aParams,method)
{
   this.initServerRequest(href,aParams,method);
   this.createXHRequest();
   this.sendXHRequest();
};
JJNode.prototype.createXHRequest = function()
{
   try
   {
      if(window.XMLHttpRequest)
      {
         try
         {
            this.xmlHttpRequest = new window.XMLHttpRequest();
         }
         catch(e)
         {
            this.xmlHttpRequest = false;
         }
      }
      if(this.xmlHttpRequest === false
         && window.ActiveXObject)
      {
         try
         {
            this.xmlHttpRequest = new window.ActiveXObject('Msxml2.XMLHTTP');
         }
         catch (e)
         {
            try
            {
               this.xmlHttpRequest = new window.ActiveXObject('Microsoft.XMLHTTP');
            }
            catch (e)
            {
               this.xmlHttpRequest = false;
            }
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJNode::createXHRequest ' + e);
   }
};
JJNode.prototype.handleXHResponse = function()
{
   try
   {
      if (this.xmlHttpRequest.readyState == 1)
      {
         this.updateActions(true);
      }
      else if (this.xmlHttpRequest.readyState == 4)
      {
         if (this.xmlHttpRequest.status == 200)
         {
            try
            {
               if(this.extractXHResponseData())
               {
                  this.updateActions(false);
               }
               else
               {
                  this.errorActions(JJError.INVALID_SERVER_CONTENT);
               }
            }
            catch(e)
            {
               this.errorActions(JJError.INVALID_SERVER_CONTENT);
            }
            
         }
         else
         {
            this.errorActions(this.xmlHttpRequest.status);
         }
      }
   }
   catch(e)
   {
      throw new JJError(e);
   }
};
JJNode.prototype.extractXHResponseData = function()
{
   var bResult = false;
   try
   {                                                                                                                       
     var nResp = null;
      if (this.xmlHttpRequest.responseXML !== undefined
          && this.xmlHttpRequest.responseXML !== null
          && !window.ActiveXObject)                                                                              
      {
         nResp = this.xmlHttpRequest.responseXML;
      }
      else if (this.xmlHttpRequest.responseText)
      {
         var aTags = this.xmlHttpRequest.responseText.replace(/\n/g,' ').split('<');
         var aSnippet = [];
         for (var i in aTags)
         {
            var str = aTags[i].replace(/^\s*|\s*$/g,'');
            if (str.length > 0 && str.search(/\?xml/) == -1 )
            {
               aSnippet[aSnippet.length] = '<' + str;
            }
         }
         nResp = document.createElement('div');                                                                                     
         nResp.innerHTML = aSnippet.join('');
      }
      if (nResp)
      {
         var nDom = document.getElementById(this.element.id);
         
         var nNew = null;
         if (nResp.getElementsByTagName && this.element.tagName)
         {
            if (nResp.getElementsByTagName('html').length > 0)
            {
               var nList = nResp.getElementsByTagName('body');
               if (nList.length > 0)
               {
                  var strOnLoad = nList[0].getAttribute('onload');
                  if (strOnLoad && strOnLoad.length > 0)
                  {
                     nList = nResp.getElementsByTagName('head');
                     if (nList.length > 0)
                     {
                        nList = nList[0].getElementsByTagName('script');
                        for (var i = 0;i < nList.length;i++)
                        {
                           eval(nList[i].text);
                        }
                     }
                     eval(strOnLoad);
                  }
               }
            }
            var nList = nResp.getElementsByTagName(this.element.tagName);
            if (nList.length == 0)
            {
               nList = nResp.getElementsByTagName(this.element.tagName.toLowerCase());
            }
            for (var i = 0;i < nList.length;i++)
            {
               if (nList[i].hasAttribute)
               {
                  if (nList[i].getAttribute('id') == this.element.id)
                  {
                     nNew = nList[i];
                     break;
                  }
               }  
               else if (nList[i].id == this.element.id)
               {
                  nNew = nList[i];
                  break;
               }
            }
         }
         
         if(nDom && nNew)
         {
            if (nNew.innerHTML && nDom.innerHTML)
            {
               nDom.innerHTML = nNew.innerHTML;
               bResult = true;
            }
            else if (nDom.hasChildNodes)
            {
               JJNode.removeElementChildren(nDom);
               var nFrag = document.createDocumentFragment();
               while (nNew.lastChild)
               {
                  var nChild = nNew.removeChild(nNew.firstChild);
                  nFrag.appendChild(nChild);
               }
               nDom.appendChild(nFrag);
               bResult = true;
            }
            else
            {
               this.errorActions(JJError.DOM_NOT_SUPPORTED);
            }
         }
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::extractXHResponseData ' + e);
   }
   return bResult;
};
JJNode.prototype.addUpdateAction = function(func)
{
   try
   {
      if (func)
      {
         this.aUpdateActions.push(func);
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::addUpdateAction ' + e);
   }
};
JJNode.prototype.updateActions = function(bResponse)
{
   try
   {
      for (var i in this.aUpdateActions)
      {
         this.aUpdateActions[i](this,bResponse);
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::updateActions ' + e);
   }
};
JJNode.prototype.addErrorAction = function(func)
{
   try
   {
      if (func)
      {
         this.aErrorActions.push(func);
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::addErrorAction ' + e);
   }
};
JJNode.prototype.errorActions = function(status)
{
   try
   {
      for (var i in this.aErrorActions)
      {
         this.aErrorActions[i](this,status);
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::errorActions ' + e);
   }
};
JJNode.prototype.sendXHRequest = function()
{
   try
   {
      if (this.xmlHttpRequestUrl)
      {
         this.xmlHttpRequest.open(this.xmlHttpRequestMethod,this.xmlHttpRequestUrl,true);
         var obj = this;
         this.xmlHttpRequest.onreadystatechange = function(){obj.handleXHResponse();};
         this.xmlHttpRequest.send(null);
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::sendXHRequest ' + e);
   }
};
JJNode.prototype.removeChildren = function()
{
   try
   {
      JJNode.removeElementChildren(this.element);
   }
   catch(e)
   {
      throw new JJError('JJNode::removeChildren ' + e);
   }
};
JJNode.prototype.hasClassName = function(strClass)
{
   var bResult = false;
   try
   {
         bResult = JJNode.elementHasClassName(this.element);
   }
   catch(e)
   {
      throw new JJError('JJNode::hasClassName ' + e);
   }
   return bResult;
};
JJNode.prototype.childJJNodes = function()
{
   var aResult = [];
   try
   {
      for (var n in this.element.children)
      {
         if (this.element.children[n] && this.element.children[n].jjNode)
         {
            aResult[aResult.length] = this.element.children[n].jjNode;
         }
      }
   }
   catch(e)
   {
      throw new JJError('JJNode::childJJNodes ' + e);
   }
   return aResult;
};
function JJField(el,strName,value,bValid)
{
   try
   {
      this.initialise();
      if (el)
      {
         this.initElement(el);
         el.value = value;
         el.name = strName;
         this.aValidators = [];
         this.bValid = bValid;
         this.aEventClasses = [];
         this.aEventClasses['click']  = {'match':'','replace':'JJFieldFocussed'};
         this.aEventClasses['focus']  = {'match':'','replace':'JJFieldFocussed'};
         this.aEventClasses['blur']   = {'match':'JJFieldFocussed','replace':'JJField'};
         this.aEventClasses['reset']  = {'match':'JJFieldNotSaved','replace':'JJFieldSaved'};
         this.aEventClasses['change'] = {'match':'JJFieldSaved','replace':'JJFieldNotSaved'};
         for (var i in JJField.aEventTypes)
         {
            var eventType = JJField.aEventTypes[i];
            this.addEventAction(eventType,function(e){return e.target.jjNode.eventHtmlClassAction(e);});
             
                var str = 'el.on' + eventType + " = function() { var e={type:'" + eventType + "',target:this}; var bR=true; var aH=el.aEventHandlers['" + eventType + "']; for(var i in aH){  if(!aH[i](e)){   bR=false;  } } return bR;}";
                eval(str);
            }
            var obj = this;
            el.aEventHandlers['change'].push(function(e){return obj.validationHandler(e);});
         
         this.replaceClassName('',JJField.className );
         if (!bValid)
         {
            this.replaceClassName('',JJField.className + 'Invalid');
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJField: ' + e);
   }
}
JJField.prototype = new JJNode({});
JJField.prototype.constructor = JJField;
JJField.aEventTypes = ['focus','blur','click','change','reset'];
JJField.className = 'JJField';
JJField.prototype.addServerRequest = function(href,aParams,method)
{
   this.initServerRequest(href,aParams,method);
   this.createXHRequest();
   
   var obj = this;
   this.addEventAction('change',function(e){return obj.sendXHRequest(e);},false);
};
JJField.prototype.changeValue = function(val)
{
   try
   {
      this.element.value = val;
   }
   catch(e)
   {
      throw new JJError('JJField::changeValue ' + e);
   }
};
JJField.prototype.handleXHResponse = function()
{
   try
   {
      if (this.xmlHttpRequest.readyState == 1)
      {
         this.updateActions(null,true);
      }
      else if (this.xmlHttpRequest.readyState == 4)
      {
         if (this.xmlHttpRequest.status == 200)
         {
            var response = this.extractXHResponseData();
            if (response !== false)
            {
               this.changeValue(response.value);
               if (response.valid)
               {
                  var e = document.createEvent('HTMLEvents');
                  e.initEvent('reset',true,true);
                  this.element.dispatchEvent(e);
               }
               else
               {
                  this.replaceClassName('JJFieldSaved','JJFieldInvalid');
               }
               this.updateActions(response,false);
            }
            else
            {
               throw new JJError('JJField::handleXHResponse data format invalid');
            }
         }
      }
   }
   catch(e)
   {
      throw new JJError(e);
   }
};
JJField.prototype.extractXHResponseData = function()
{
   var result = false;
   try
   {
      var s = this.xmlHttpRequest.responseText;
      var i = s.search(/^{valid:(true)|(false)\,value:\".*?\"\,alert:\{text:\".*?"\,hint:\".*?\"}}$/);
      if (i >= 0)
      {
         eval('result = ' + s);
      }
   }
   catch(e)
   {
      throw new JJError('JJField::extractXHResponseData ' + e);
   }
   return result;
};
JJField.prototype.updateActions = function(r,bResponse)
{
   try
   {
      for (var i in this.aUpdateActions)
      {
         this.aUpdateActions[i](this,r,bResponse);
      }
   }
   catch(e)
   {
      throw new JJError('JJField::updateActions ' + e);
   }
};
JJField.prototype.sendXHRequest = function(e)
{
   try
   {
      if (this.xmlHttpRequestUrl && this.validate())
      {
         this.xmlHttpRequestUrl += '&' + this.element.name + '=' + encodeURIComponent(this.element.value);
         this.xmlHttpRequest.open(this.xmlHttpRequestMethod,this.xmlHttpRequestUrl,true);
         var obj = this;
         this.xmlHttpRequest.onreadystatechange = function(){obj.handleXHResponse();};
         this.xmlHttpRequest.send(null);
      }
   }
   catch(e)
   {
      throw new JJError('JJField::sendXHRequest ' + e);
   }
   return true;
};
JJField.prototype.addValidator = function(o)
{
   try
   {
      if (o)
      {
         this.aValidators.push(o);
      }
   }
   catch(e)
   {
      throw new JJError('JJField::addValidator ' + e);
   }
};
JJField.prototype.validate = function()
{
   var bResult = true;
   try
   {
      for (var i in this.aValidators)
      {
         if (this.aValidators[i].validate && !this.aValidators[i].validate(this))
         {
            bResult = false;
         }
      }
      if (!bResult)
      {
         this.replaceClassName('JJFieldSaved','JJFieldInvalid');
      }
      else
      {
         this.replaceClassName('JJFieldInvalid','');
      }
   }
   catch(e)
   {
      throw new JJError('JJField::validate ' + e);
   }
   this.bValid = bResult;
   return bResult;
};
JJField.prototype.validationHandler = function(e)
{
   try
   {
      this.validate();
   }
   catch(e)
   {
      throw new JJError('JJField::validationHandler ' + e);
   }
   return true;
};
JJField.prototype.eventHtmlClassAction = function(e)
{
   var jjF = e.target.jjNode;
   if (jjF.aEventClasses && jjF.aEventClasses[e.type] !== undefined)
   {
      jjF.replaceClassName(jjF.aEventClasses[e.type].match,
                           jjF.aEventClasses[e.type].replace);
   }
   return true;
};
function JJFieldValidator()
{
   try
   {
      this.aActions = [];
   }
   catch (e)
   {
      throw new JJError('JJFieldValidator: ' + e);
   }
}
JJFieldValidator.prototype.addAction = function(func)
{
   var bResult = false;
   try
   {
     this.aActions.push(func);
   }
   catch (e)
   {
      throw new JJError('JJFieldValidator: ' + e);
   }
   return bResult;
};
JJFieldValidator.prototype.validate = function(o)
{
   var bResult = true;
   try
   {
      this.internalValidate();
      for (var i in this.aActions)
      {
         if (!this.aActions[i](o))
         {
            bResult = false;
         }
      }
   }
   catch(e)
   {
      throw new JJError('JJFieldValidator: ' + e);
   }
   return bResult;
};
JJFieldValidator.prototype.internalValidate = function(o)
{
   var bResult = true;
   try
   {
   }
   catch(e)
   {
      throw new JJError('JJFieldValidator: ' + e);
   }
   return bResult;
};
function JJPanel(el)
{
   try
   {
      this.initialise();
      if (el)
      {
         this.initElement(el);
         
         
      }
   }
   catch (e)
   {
      throw new JJError('JJPanel: ' + e);
   }
}
JJPanel.prototype = new JJNode({});
JJPanel.prototype.constructor = JJPanel;
JJPanel.className = 'JJPanel';
JJPanel.prototype.minimisePanel = function()
{
   this.panelState = 'min';
   this.replaceClassName('JJPanelClosed','');
   this.replaceClassName('JJPanelOpen','JJPanelMinimised');
   var nL = this.element.getElementsByTagName('div');
   for (var i = 0;i < nL.length;i++)
   {
      if (JJNode.elementHasClassName(nL[i],'JJPanelContent'))
      {
         JJNode.replaceElementClassName(nL[i],'','JJPanelClosed');
      }
   }
};
JJPanel.prototype.openPanel = function(complete)
{
   if (complete !== true)
   {
      this.panelState = 'open';
      this.replaceClassName('JJPanelClosed','JJPanelOpen');
      this.replaceClassName('JJPanelMinimised','');
      var nL = document.getElementsByTagName('div');
      for (var i = 0;i < nL.length;i++)
      {
         if (nL[i] && nL[i].className && nL[i].className.search(/JJPanelContent/) != -1)
         {
            JJNode.replaceElementClassName(nL[i],'JJPanelClosed','');
         }
      }
      this.panelEffects('open');
   }
};
JJPanel.prototype.closePanel = function(complete)
{
   if (complete !== true)
   {
      this.panelState = 'closed';
      if (!this.panelEffects('close'))
      {
         this.replaceClassName('JJPanelOpen','JJPanelClosed');
      }
   }
   else
   {
      this.replaceClassName('JJPanelOpen','JJPanelClosed');
   }
};
JJPanel.prototype.togglePanel = function()
{
   if (this.panelState != 'open')
   {
      this.panelState = 'open';
      this.openPanel();
   }
   else
   {
      this.panelState = 'minimised';
      this.minimisePanel();
   }
};
JJNode.prototype.addEffects = function(jjPE)
{
   try
   {
      this.jjPanelEffects = jjPE;
   }
   catch (e)
   {
      throw new JJError('JJPane::addEffects ' + e);
   }
};
JJNode.prototype.panelEffects = function(strAction)
{
   var bResult = false;
   try
   {
      var func = null;
      
      if (this.jjPanelEffects)
      {
         eval('func = this.jjPanelEffects.' + strAction);
         if (func)
         {
            eval('bResult = this.jjPanelEffects.' + strAction + "(this)" );
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJPane::panelEffects ' + e);
   }
   return bResult;
};
function JJPanelEffects()
{
   try
   {
      
   }
   catch (e)
   {
      throw new JJError('JJPanelEffects: ' + e);
   }
}
JJPanelEffects.aActionData = [];
JJPanelEffects.timerInterval = 50;
JJPanelEffects.prototype.close = function(jjP)
{
   var bResult = true;
   try
   {
      if (jjP.element)
      {
         bResult = false;
         
         if (JJPanelEffects.aActionData[jjP.id()] === undefined)
         {
            var obj = this;
            var id = jjP.id();
            var el = jjP.element;
            var ref = setInterval(function(){obj.closeAction(id,el);},JJPanelEffects.timerInterval);
            if (JJPanelEffects.aActionData[jjP.id()] === undefined)
            {
               JJPanelEffects.aActionData[jjP.id()] =  obj.initActionData(jjP,ref);
            }
            else
            {
               JJPanelEffects.aActionData[jjP.id()]['timerRef'] = ref;
            }
            bResult = true;
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJPanelEffects.close: ' + e);
   }
   return bResult;
};
JJPanelEffects.prototype.initActionData = function(jjP,ref)
{
   return {jjPanel:jjP,opacity:1.0,timerRef:ref};
};
JJPanelEffects.prototype.closeAction = function(id,el)
{
   try
   {
      var objData = JJPanelEffects.aActionData[id];
      if (objData.opacity > 0.0)
      {
         objData.opacity -= 0.1;
         if (objData.opacity < 0.0)
         {
            objData.opacity = 0.0;
         }
         if (!el.style)
         {
            el.style = {filter:'alpha(' + parseInt(objData.opacity * 100) + ')',opacity:objData.opacity};
         }
         else
         {
            el.style.filter = 'alpha(' + parseInt(objData.opacity * 100) + ')';
            el.style.opacity = objData.opacity;
         }
      }
      if (objData.opacity == 0.0)
      {
         clearInterval(objData.timerRef);
         if (objData.jjPanel.closePanel)
         {
            objData.jjPanel.closePanel(true);
         }
         delete JJPanelEffects.aActionData[id];
      }
   }
   catch (e)
   {
      throw new JJError('JJPanelEffects.closeAction: ' + e);
   }
};
JJPanelEffects.prototype.open = function(jjP)
{
   var bResult = true;
   try
   {
      if (jjP.element)
      {
         if (JJPanelEffects.aActionData[jjP.id()])
         {
            clearInterval(JJPanelEffects.aActionData[jjP.id()].timerRef);
            delete JJPanelEffects.aActionData[jjP.id()];
         }
         if (jjP.element.style)
         {
            jjP.element.style.filter = 'alpha(100)';
            jjP.element.style.opacity = 1.0;
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJPanelEffects.open: ' + e);
   }
   return bResult;
};
function JJPEShrink()
{
   try
   {
      
   }
   catch (e)
   {
      throw new JJError('JJPEShrink: ' + e);
   }
}
JJPEShrink.prototype = new JJPanelEffects();
JJPEShrink.prototype.initActionData = function(jjP,ref)
{
   var cs = JJNode.getElComputedStyle(jjP.element);
   var iH = cs !== null? parseInt(cs.height) : null;
   var iW = cs !== null? parseInt(cs.width) : null;
   var iT = cs !== null? parseInt(cs.top) : null;
   var iL = cs !== null? parseInt(cs.left) : null;
   return {jjPanel:jjP,
           style:{height:iH,width:iW,top:iT,left:iL},
           initialStyle:{height:iH,width:iW,top:iT,left:iL},
           timerRef:ref};
};
JJPEShrink.prototype.closeAction = function(id,el)
{
   function close(objData,id)
   {
      clearInterval(objData.timerRef);
      if (objData.jjPanel.closePanel)
      {
         objData.jjPanel.closePanel(true);
      }
   }
   
   try
   {
      var objData = JJPanelEffects.aActionData[id];
      if (objData.style.height == null)
      {
         close(objData,id);
      }
      else
      {
         if (parseInt(objData.style.height) > 0)
         {
            var iH = parseInt(parseInt(objData.style.height) * 0.7);
            var iT = parseInt(objData.style.top + (parseInt(objData.style.height) - iH)/2);
            objData.style.height = iH > 0? iH : 0;
            var iW = parseInt(parseInt(objData.style.width) * 0.7);
            var iL = parseInt(objData.style.left + (parseInt(objData.style.width) - iW)/2);
            objData.style.width = iW > 0? iW : 0;
            if (!el.style)
            {
               el.style = {height:objData.style.height + 'px',
                           width:objData.style.width + 'px',
                           top:objData.style.top + 'px',
                           left:objData.style.left + 'px',
                           overflow:'hidden',
                           position:'absolute'};
            }
            else
            {
               el.style.height = objData.style.height + 'px';
               el.style.width = objData.style.width + 'px';
               el.style.top = objData.style.top + 'px';
               el.style.left = objData.style.left + 'px';
            }
            if (document.createTreeWalker)
            {
               var ni = document.createTreeWalker(el,NodeFilter.SHOW_ELEMENT,null,false);
               var n = ni.nextNode();
               while (n)
               {
                  var cs = JJNode.getElComputedStyle(n);
                  if (cs)
                  {
                     var iF = parseInt(parseInt(cs.fontSize) * 0.9);
                     if (!n.style)
                     {
                        n.style = {fontSize:iF + 'px'};
                     }
                     else
                     {
                        n.style.fontSize = iF + 'px';
                     }
                  }
                  n = ni.nextNode();
               }
            }
         }
         if (iH == 0)
         {
            close(objData,id);
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJPEShrink.closeAction: ' + e);
   }
};
JJPEShrink.prototype.open = function(jjP)
{
   var bResult = true;
   try
   {
      if (jjP.element)
      {
         var iH = null;
         var iW = null;
         if (JJPanelEffects.aActionData[jjP.id()] != undefined)
         {
            clearInterval(JJPanelEffects.aActionData[jjP.id()].timerRef);
            iH = JJPanelEffects.aActionData[jjP.id()].initialStyle.height;
            iW = JJPanelEffects.aActionData[jjP.id()].initialStyle.width;
            iT = JJPanelEffects.aActionData[jjP.id()].initialStyle.top;
            iL = JJPanelEffects.aActionData[jjP.id()].initialStyle.left;
         }
         if (jjP.element.style && iH && iW)
         {
            jjP.element.style.height = iH + 'px';
            jjP.element.style.width = iW + 'px';
            jjP.element.style.top = iT + 'px';
            jjP.element.style.left = iL + 'px';
            if (jjP.element.style.overflow)
            {
               delete jjP.element.style.overflow;
            }
            if (jjP.element.style.position)
            {
               delete jjP.element.style.position;
            }
         }
      }
   }
   catch (e)
   {
      throw new JJError('JJPEShrink.open: ' + e);
   }
   return bResult;
};