/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}


// From the book Pro Javascript Design Patterns, page 43.
var Wsf = 
{
   Extend: function (subClass, superClass) {
      var F = function() {};
      F.prototype = superClass.prototype;
      subClass.prototype = new F();
      subClass.prototype.constructor = subClass;
   }
}

var WsfElement = 
{
   Move: function(element,x,y,w,h) {
     element.style.left = x + "px";
     element.style.top = y + "px";
     if (w !== null) element.style.width = w + "px";
     if (h !== null) element.style.height = h + "px";
   },

   SetSize: function(element,w,h) {
     if (w !== null) element.style.width = w + "px";
     if (h !== null) element.style.height = h + "px";
   }
}

Element.addMethods(WsfElement);
                                                         
/*****************************************************************************/
function CWsf_App(lang)
{
   this.DetectBrowser()

   this.aCtrls = [];
   this.RootCtrl = null;
   this.lang = lang;
}

/*****************************************************************************/
CWsf_App.prototype.OnBodyLoad = function()
{
   this.ImplementMouseCapture();

   // Init controls
   
   this.RootCtrl.Init();
   this.RootCtrl.UpdateUI();   
   
   // Resize
   
   Event.observe(window, 'resize', this._OnResize.bindAsEventListener(this));
   this._OnResize();            
   
   // Start automatic UI update

   new PeriodicalExecuter(this.RootCtrl.UpdateUI.bind(this.RootCtrl), .25);
}

/*****************************************************************************/
CWsf_App.prototype.DetectBrowser = function()
{
   this.IsIE = false;
   this.IsGecko = false;
   this.fBrowserVersion = 0;
   var s = navigator.userAgent.toLowerCase();
   var body = $(document.body);
   
   this.features = { };
   this.features.modalDialog = window.showModalDialog != undefined;
   
   if (s.indexOf("opera")!=-1)
   {
   	// dummy
   }
   else if (s.indexOf("gecko")!=-1)
   {
   	this.IsGecko = true;
      body.addClassName("gecko");
   }
   else if (s.indexOf("msie")!=-1)
   {
      this.IsIE = true;
		var aVersion = navigator.appVersion.split("MSIE")
		this.fBrowserVersion = parseFloat(aVersion[1]);
      body.addClassName("ie");
      body.addClassName("ie"+this.fBrowserVersion);
      this.isIE6 = this.IsIE && this.fBrowserVersion == 6;
   }
}

/*****************************************************************************/
CWsf_App.prototype.ImplementMouseCapture = function()
{
	if (this.IsIE) return;
	
 	var capture = ["click", "mousedown", "mouseup", "mousemove", "mouseover", "mouseout" ]; 

   HTMLElement.prototype.setCapture = function()
   { 
   	if (this._capture != null) return;
   	
		var self = this; 
		var flag = false; 
		
		this._capture = function(e)
		{ 
		   if (flag) return;
		   flag = true; 
		   
		   var event = document.createEvent("MouseEvents"); 
		   
		   event.initMouseEvent(e.type, 
		       e.bubbles, e.cancelable, e.view, e.detail, 
		       e.screenX, e.screenY, e.clientX, e.clientY, 
		       e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 
		       e.button, e.relatedTarget); 

		   self.dispatchEvent(event); 
		   flag = false; 
		}; 
		
		for (var i=0; i<capture.length; i++) 
		{ 
		   window.addEventListener(capture[i], this._capture, true); 
		} 
	}

   HTMLElement.prototype.releaseCapture = function()
   { 
   	if (this._capture == null) return;
   	
   	for (var i=0; i<capture.length; i++) 
   	{ 
      	window.removeEventListener(capture[i], this._capture, true); 
      } 
      
      this._capture = null; 
   }
}

/*****************************************************************************/
CWsf_App.prototype.SetCookie = function(sName, sValue, IsGlobal)
{
  //date = new Date();
  
  var s = sName + "=" + escape(sValue);
  if (IsGlobal) s += "; path" + "=/";      // to make HTTRACK dizzy ;-)
  // + "; expires=" + date.toGMTString();
  
  document.cookie = s;
}

/*****************************************************************************/
CWsf_App.prototype.GetCookie = function (sName, DefValue)
{
  // cookies are separated by semicolons
  // IE bug: cookies in total can have up-to 4096KB
  var aCookie = document.cookie.split("; ");
  
  for (var i=0; i < aCookie.length; i++)
  {
    // a name/value pair (a crumb) is separated by an equal sign
    var aCrumb = aCookie[i].split("=");
    
    if (sName == aCrumb[0]) return unescape(aCrumb[1]);
  }

  // a cookie with the requested name does not exist
  return DefValue;
}

/*****************************************************************************/
CWsf_App.prototype.GetCookieInt = function (sName, DefValue)
{
	return parseInt(this.GetCookie(sName, DefValue));
}

/*****************************************************************************/
CWsf_App.prototype.Refresh = function ()
{
   window.location.reload();
}

/*****************************************************************************/
CWsf_App.prototype.Navigate = function (url)
{
   window.location.href = url;
}

/*******************************************************************************/
/*
/* WINDOWS
/*
/*******************************************************************************/
    
/*****************************************************************************/
CWsf_App.prototype.OpenPopup = function(url, sName, w, h)
{
  w += 32;
  h += 96;
  var wleft = (screen.width - w) / 2;
  var wtop = (screen.height - h) / 2;
  
  var win = window.open(url,
    sName,
    'width=' + w + ', height=' + h + ', ' +
    'left=' + wleft + ', top=' + wtop + ', ' +
    'location=no, menubar=no, ' +
    'status=no, toolbar=no, scrollbars=yes, resizable=yes');
  
  // Just in case width and height are ignored
  //win.resizeTo(w, h);
  
  // Just in case left and top are ignored
  //win.moveTo(wleft, wtop);
  win.focus();

  return win;
}

/*****************************************************************************/
CWsf_App.prototype.OpenDialog = function(url, mapParams, CallbackCtrl, sCallbackName)
{
   var w = 500;
   var h = 400;
//   w += 32;
//   h += 96;
   var wleft = (screen.width - w) / 2;
   var wtop = (screen.height - h) / 2;

   var winName = hex_md5(url);
   var query = '';
   
   for (k in mapParams)
   {
      query += "&"+k+"="+encodeURIComponent(mapParams[k]);
   }

   if (CallbackCtrl)
   {
      query += "&_callbackCtrlId="+CallbackCtrl.GetId()+"&_callbackName="+sCallbackName;
   }
   
   if (query)
   {
      if (url.indexOf("?") != -1) 
         url += query;
      else {
         url += '?';
         url += query.substring(1);
      }
   }
   
//   if (this.features.modalDialog)
//   {
//      window.showModalDialog(url, null, 
//        'dialogWidth: ' + w + 'px; dialogHeight: ' + h + 'px; ' +
//        'resizable: yes; center: yes'
//        );
//      return null;
//   }
//   else
   {
      var win = window.open(url,
        winName,
        'width=' + w + ', height=' + h + ', ' +
        'left=' + wleft + ', top=' + wtop + ', ' +
        'location=no, menubar=no, status=no, toolbar=no, scrollbars=yes, resizable=yes');

      win.focus();
      return win;
   }
}

/*****************************************************************************/
CWsf_App.prototype.ShowErrorBox = function(sHtml)
{
//   var o = this.GetCtrlById(this.sMsgBoxId);
//   
//   if (o) 
//      o.ShowBox(sHtml, CWsf_Ctrls_MsgBox.TYPE_ERROR, 300);   
//   else
      alert(sHtml);
}

/*****************************************************************************/
CWsf_App.prototype.ShowInfoBox = function(sHtml)
{
//   var o = this.GetCtrlById(this.sMsgBoxId);
//   
//   if (o) 
//      o.ShowBox(sHtml, CWsf_Ctrls_MsgBox.TYPE_INFO, 300);   
//   else
      alert(sHtml);
}

/*******************************************************************************/
/*
/* CONTROLS
/*
/*******************************************************************************/
           
/*****************************************************************************/
CWsf_App.prototype.RegisterCtrl = function (Ctrl)
{
   this.aCtrls[Ctrl.GetId()] = Ctrl;
}

/*****************************************************************************/
CWsf_App.prototype.GetCtrlById = function (sId)
{
   return sId ? this.aCtrls[sId] : null;
}

/*******************************************************************************/
/*
/* CMDS
/*
/*******************************************************************************/

/*******************************************************************************/
CWsf_App.prototype.UpdateUI = function ()
{
   this.RootCtrl.UpdateUI();
}

/*******************************************************************************/
CWsf_App.prototype.InvokeUpdateCmd = function (SourceCtrl, sCmdId, CmdUI)
{
   var sMethod = "OnUpdate"+sCmdId;
   
   var a = SourceCtrl.CmdTarget ? SourceCtrl.CmdTarget : SourceCtrl;
   
   for (; a; a=a.GetParent())
   {
      if (a[sMethod] != undefined)
      {
         a[sMethod](CmdUI);
         break;
      }
      else if (a.OnUpdateCmdUI(sCmdId, CmdUI))
         break;
   }
}

/*******************************************************************************/
CWsf_App.prototype.InvokeCmd = function (SourceCtrl, sCmdId, Params)
{
   // Ensure cmd is enabled

   var CmdUI = { 
      IsEnable: true,
      Enable: function (IsEnable) { this.IsEnable = IsEnable; },
      Check: function (IsChecked) { }
   };
   
   this.InvokeUpdateCmd(SourceCtrl, sCmdId, CmdUI);
   if (!CmdUI.IsEnable) return;
   
   // Handle on client
   
   var sMethod = "On"+sCmdId;
   var cmdTarget = SourceCtrl.CmdTarget ? SourceCtrl.CmdTarget : SourceCtrl;
   
   for (var a=cmdTarget; a; a=a.GetParent())
   {
      if (a[sMethod] != undefined)
      {
         if (a[sMethod](Params)) return;
         break;
      }
      else 
      {
         switch (a.OnCommand(sCmdId, Params))
         {
         case CWsf_Ctrls_Control.CMD_HANDLE_ON_SERVER: a = null; break;
         case CWsf_Ctrls_Control.CMD_HANDLED: return;
         }
      }
      
      if (!a) break;
   }
   
   // Handle on server
                                        
   var ctrlsState = {};
   g_App.RootCtrl.SaveState(ctrlsState);
   
   var a = { sCmd: sCmdId, Params: Params, sSrcCtrlId: cmdTarget.GetId(), ctrlsState: ctrlsState };
      
   var e = $('wsfFormState');
   e.value = Object.toJSON(a); 
   
   $('wsfForm').submit();         
}

/*******************************************************************************/
/*
/* RPC
/*
/*******************************************************************************/

/**
* @deprecated
*/
CWsf_App.prototype.DoRPC = function(sClassMethod, Params, fnOnSuccess, fnOnFailure)
{
   var self = this;
   
   var url = '/rpc.php?m='+encodeURIComponent(sClassMethod);
                                        
   if (Params)
   {
      url += "&p="+encodeURIComponent(Object.toJSON(Params));
      url += "&l="+this.lang;
   }
   
   new Ajax.Request(url,
      {
         method: 'get',
         
         onSuccess: function (transport) { if (fnOnSuccess) fnOnSuccess(transport.responseText ? transport.responseText.evalJSON() : null); },
         
         onFailure: 
            fnOnFailure ? 
               function (transport) { fnOnFailure(transport.responseText ? transport.responseText.evalJSON() : null); } :
               function (transport) { self.ShowErrorBox(transport.responseText ? transport.responseText.evalJSON() : null); }   
      });         
}

/*******************************************************************************/
CWsf_App.prototype.CallServerMethod = function(ctrl, method, params, fnOnSuccess, fnOnFailure)
{
   if (this._activeServerMethodCall) { alert('wait'); return; }
   
   new Ajax.Request(document.location.href,
      {
         method: 'post',
         
         parameters: { rpc: true, ctrlId: ctrl.GetId(), method: method, params: Object.toJSON(params) },
         
         onSuccess: function (transport) { new CWsf_Web_CallServerMethodHandler(fnOnSuccess, transport); },
         
         onFailure: 
            fnOnFailure ? 
               function (transport) { fnOnFailure(transport.responseText ? transport.responseText.evalJSON() : null); } :
               function (transport) { g_App.ShowErrorBox(transport.responseText ? transport.responseText.evalJSON() : null); }   
      });         
}

/*******************************************************************************/
/*
/* EVENTS
/*
/*******************************************************************************/

CWsf_App.prototype._OnResize = function (ev)
{
   if (this._inResize) return;   // IE calls resize multiple times
   this._inResize = true;
   
   this.RootCtrl.OnSize();

   this._inResize = false;
}


/*******************************************************************************/
function CWsf_Ctrls_Control(svrProp)
{
   // Wake properties from the server. 
   // Some controls must not be yet created so woke them up in Init().
   // Keep the original values as JSON to optimize POST.
   
   if (svrProp)
   {
      for (var name in svrProp) 
      {
         var value = svrProp[name];
         svrProp[name] = Object.toJSON(value);
         this[name] = this._DecodeStateVariable(value);
      }   
   }
   
   // ...
   
   if (this._parent) 
      this._parent._children.push(this);
   else 
      g_App.RootCtrl = this;  

   // ...
   
   this._svrProp = svrProp;
   this._classes = ['CWsf_Ctrls_Control'];
   g_App.RegisterCtrl(this);
   this._width = this._w;
   this._height = this._h;
   this._clientWidth = this._clientHeight = null;
   this._events = [];
   this._children = [];

   this.Elem = $(this._id);
   if (this.Elem) this.Elem.WsfCtrl = this;
   
   this._layout = this._childrenLayout ? eval('new '+this._childrenLayout+'(this);') : null;
      
   if (!this._enabled) this.Enable(false);
}

CWsf_Ctrls_Control.prototype.CMD_HANDLED = 1;
CWsf_Ctrls_Control.prototype.CMD_HANDLE_ON_SERVER = 2;
CWsf_Ctrls_Control.prototype.CMD_NOT_HANDLED = 3;

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._DecodeStateVariable = function (value)
{
   if (value === null)
   {
      return value;
   }
   else if (typeof(value) == "string")
   {
      if (value.charAt(0) == '*')
         return value.substr(1);
      else {
         var c = g_App.GetCtrlById(value);
         return c ? c : { _proxyCtrl : value };
      }
   }
   else if (typeof(value) == "object")
   {
      if (Object.isArray(value))
      {
         for (var i=0; i < value.length; ++i)
         {
            value[i] = this._DecodeStateVariable(value[i]);
         }      
         return value;
      }
      else if (value._proxyCtrl)
      {
         return g_App.GetCtrlById(value._proxyCtrl);
      }
      else
      {
         for (var name in value)
         {
            value[name] = this._DecodeStateVariable(value[name]);
         }      
         return value;
      }
   }
   else
   {
      return value;
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._DecodeProxyCtrl = function (value)
{
   if (value === null)
   {
      return value;
   }
   else if (typeof(value) == "object")
   {
      if (Object.isArray(value))
      {
         for (var i=0; i < value.length; ++i)
         {
            value[i] = this._DecodeProxyCtrl(value[i]);
         }      
         return value;
      }
      else if (value.IsA)
      {
         return value;
      }
      else if (value._proxyCtrl)
      {
         return g_App.GetCtrlById(value._proxyCtrl);
      }
      else
      {
         for (var name in value)
         {
            value[name] = this._DecodeProxyCtrl(value[name]);
         }      
         return value;
      }
   }
   else
   {
      return value;
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.Init = function ()
{
   // Process control proxies
                                                
   if (this._svrProp)
   {
      for (var name in this._svrProp)
      {
         this[name] = this._DecodeProxyCtrl(this[name]);
//         console.log("%s.%s = %s -> %s", this.GetId(), name, this._svrProp[name], this[name]);
      }
   }
   
   // ...
   
   for (var i=0; i < this._children.length; ++i)
   {
      this._children[i].Init();    
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._AddClass = function (sClass)
{
   this._classes.push(sClass);
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.IsA = function (sClass)
{
   return this._classes.indexOf(sClass) != -1;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetAncestorByClass = function (sClass)
{
   for (var o=this; o; o=o._parent)
   {
      if (o.IsA(sClass)) return o;
   }
   return null;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetView = function ()
{
   return CWsf_Ctrls_ViewHtml.prototype._instance;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetTitle = function ()
{
   return this._title;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetId = function ()
{
   return this._id;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetParent = function ()
{
   return this._parent;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetChildByIdx = function (nIdx)
{
   return this._children[nIdx];
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetChildCount = function ()
{
   return this._children.length;
}


/*******************************************************************************/
CWsf_Ctrls_Control.prototype.UpdateUI = function ()
{
   for (var i=0; i < this._children.length; ++i)
   {
      this._children[i].UpdateUI();    
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetForm = function ()
{
   for (var p = this; p && !p.IsA("CWsf_Forms_CtrlForm"); p=p._parent) /* dummy */;
   
   return p;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.Focus = function ()
{
   if (!this.IsVisible() || !this.IsEnabled()) return false;
   
   this.Elem.focus();   
   return true;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.HasFocus = function ()
{
   return this.GetView().GetFocus() == this;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.Enable = function (isEnabled)
{
   if (isEnabled) 
      this.Elem.removeClassName('disabled'); 
   else 
      this.Elem.addClassName('disabled'); 
   
   this.Elem.disabled = !isEnabled;
   this._enabled = isEnabled;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.IsEnabled = function ()
{
   return this._enabled;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.IsEnabled = function ()
{
   return this._enabled;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.IsReadOnly = function ()
{
   return this._readOnly;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetStyle = function (style, defValue)
{
   return this._styles && this._styles[style] ? this._styles[style] : defValue;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.GetComputedStyle = function (style, defValue)
{
   switch (style)
   {
   case 'marginTop':
      var n = this.GetStyle('marginTop', 0);
      if (!n) n = this.GetStyle('margin', 0);
      return n;

   case 'marginBottom':
      var n = this.GetStyle('marginBottom', 0);
      if (!n) n = this.GetStyle('margin', 0);
      return n;
      
   default:
      return this.GetStyle(style, defValue);
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.CallServerMethod = function (method, params, fnOnSuccess, fnOnFailure)
{
   g_App.CallServerMethod(this, method, params, fnOnSuccess, fnOnFailure); 
}

/*******************************************************************************/
/* 
/* STATE
/*
/*******************************************************************************/

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.SaveState = function (ctrlsState)
{
   var state = this._GetControlState();
   // save only if non-empty
   for (var name in state) { ctrlsState[this.GetId()] = state; break; } 
   
   for (var i=0; i < this._children.length; ++i)
   {
      this._children[i].SaveState(ctrlsState);
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._EncodeVariable = function (value)
{
   if (value === null)
   {
      return value;
   }
   else if (typeof(value) == "object")
   {
      if (value.IsA)
      {
         return value.GetId();
      }
      else if (Object.isArray(value))
      {
         var newArray = [];
         
         for (var i=0; i < value.length; ++i)
         {
            newArray[i] = this._EncodeVariable(value[i]);
         }
         
         return newArray;
      }
      else
      {
         var newObj = {};
         
         for (var name in value)
         {
            newObj[name] = this._EncodeVariable(value[name]);
         }
         
         return newObj;
      }
   }
   else if (typeof(value) == "string")
   {
      return "*"+value;
   }
   else 
   {
      return value;
   }
}

/**
* Returns a state object to send to the server.
*/
CWsf_Ctrls_Control.prototype._GetControlState = function ()
{
   if (!this._svrProp) return {};

   var state = { };

   for (var name in this._svrProp) 
   {
      var newValue = this._EncodeVariable(this[name]);
      if (Object.toJSON(newValue) != this._svrProp[name]) state[name] = newValue;
   }

   return state;
}

/*******************************************************************************/
/* 
/* VISIBILITY
/*
/*******************************************************************************/

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.IsVisible = function ()
{
   return this._visible;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.Show = function (isShow)
{
   if (isShow || isShow == undefined) 
   {
      if (!this.IsVisible())
      {
//         this.Elem.removeClassName("hidden");
         this.Elem.show();
         this._visible = true;
      }
   }
   else 
   {
//      this.Elem.addClassName("hidden");
      this.Elem.hide();
      this._visible = false;
   }

   if (this._parent) this._parent.OnSize();
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.Hide = function ()
{
   this.Show(false);
}

/*******************************************************************************/
/* 
/* POSITION & SIZE
/*
/*******************************************************************************/

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._ClearSizeCache = function ()
{
   this._width = null;
   this._height = null;
   this._clientWidth = null;
}

/*******************************************************************************/
// Slow!
CWsf_Ctrls_Control.prototype._CacheWidth = function ()
{
   this._width = this.Elem.offsetWidth;
}

/*******************************************************************************/
// Slow!
CWsf_Ctrls_Control.prototype._CacheHeight = function ()
{
   this._height = this.Elem.offsetHeight;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._CacheClientSize = function ()
{
   this._clientWidth = this.Elem.clientWidth;
   this._clientHeight = this.Elem.clientHeight;
}

/*******************************************************************************/
// content+padding+border
CWsf_Ctrls_Control.prototype.GetSize = function ()
{
   if (this._width === null) this._CacheWidth();
   if (this._height === null) this._CacheHeight();
   return { width: this._width, height: this._height };
}

/*******************************************************************************/
// content+padding+border
CWsf_Ctrls_Control.prototype.GetWidth = function () 
{
   if (this._width === null) this._CacheWidth();
   return this._width;
}

/*******************************************************************************/
// content+padding+border
CWsf_Ctrls_Control.prototype.GetHeight = function () 
{
   if (this._height === null) this._CacheHeight();
   return this._height;
}

/*******************************************************************************/
// content+padding 
CWsf_Ctrls_Control.prototype.GetClientSize = function ()
{
   if (this._clientWidth === null) this._CacheClientSize();
   return { width: this._clientWidth, height: this._clientHeight };
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.Move = function (nX,nY,nW,nH)
{
   var s = this.Elem.style;
   
   if (nX < 0) nX = 0;
   if (nY < 0) nY = 0;
   
   s.position = "absolute";
   s.left = nX+"px";
   s.top = nY+"px";
   
   if (nW !== null || nH !==null)
   {
      this.SetSize(nW, nH);
   }
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._GetPaddingBorderSizes = function() 
{
   return this._border;

   // NOTE: getComputedStyle() is very slow
//   var s = window.getComputedStyle ? window.getComputedStyle(this.Elem,null) : this.Elem.currentStyle;

//   var a = [
//      parseInt(s.borderTopWidth),
//      parseInt(s.borderRightWidth),
//      parseInt(s.borderBottomWidth),
//      parseInt(s.borderLeftWidth)
//      ];

//   if (isNaN(a[0])) a[0] = 0;
//   if (isNaN(a[1])) a[1] = 0;
//   if (isNaN(a[2])) a[2] = 0;
//   if (isNaN(a[3])) a[3] = 0;
//   
//   var b = [];
//   b[0] = parseInt(s.paddingTop);
//   b[1] = parseInt(s.paddingRight);
//   b[2] = parseInt(s.paddingBottom);
//   b[3] = parseInt(s.paddingLeft);

//   if (isNaN(b[0])) b[0] = 0;
//   if (isNaN(b[1])) b[1] = 0;
//   if (isNaN(b[2])) b[2] = 0;
//   if (isNaN(b[3])) b[3] = 0;
//   
//   a[0] += b[0];
//   a[1] += b[1];
//   a[2] += b[2];
//   a[3] += b[3];

//   return a;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.SetSize = function (nW,nH)
{
   var s = this.Elem.style;
   s.overflow = "auto";
   var b = this._GetPaddingBorderSizes();
   
   if (nW !== null) 
   {
      this._width = nW;
      nW -= b[1] + b[3];
      if (nW < 0) nW = 0;
      s.width = nW + "px";
      this._clientWidth = nW;
   }
   
   if (nH !== null) 
   {
      this._height = nH;
      nH -= b[0] + b[2];
      if (nH < 0) nH = 0;
      s.height = nH  + "px";
      this._clientHeight = nH;
   }

   this.OnSize();
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.OnSize = function ()
{
   if (!this.IsVisible()) return;
   
   if (this._layout) 
   {
      // Custom layout
      this.Elem.style.overflow = "hidden";
      this._layout.LayoutChildren(this);
   }
   else
   {
      // Default HTML layout of children
      for (var i=0,n=this._children.length; i < n; ++i)
      {
         var o = this._children[i];
         o._ClearSizeCache();
         o.OnSize();
      }   
   }   
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.SetZIndex = function (zIndex)
{
   this.Elem.style.zIndex = zIndex;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.MoveBelow = function (ctrl)
{
   this.Elem.style.zIndex = ctrl.Elem.style.zIndex - 1;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.SetOpacity = function (opacityFloat)
{
   this.Elem.setOpacity(opacityFloat);
}

/*******************************************************************************/
/* 
/* CUSTOM EVENTS
/*
/*******************************************************************************/

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.AttachEventHandler = function (eventName, fnCallback)
{
   if (this._events[eventName] == undefined) { this._events[eventName] = []; }
   
   this._events[eventName].push(fnCallback);
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.RaiseEvent = function (eventName, eventData)
{
   if (this._events[eventName] == undefined) return;
   
   for (var i=this._events[eventName].length; i--;)
   {
      this._events[eventName][i](eventData);
   }
}

/*******************************************************************************/
/* 
/* COMMANDS
/*
/*******************************************************************************/

/*******************************************************************************/
CWsf_Ctrls_Control.prototype._GetCmdTarget = function ()
{
   return this._cmdTarget ? this._cmdTarget : this;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.OnCommand = function (sCmdId, Params)
{
   return this.CMD_NOT_HANDLED;
}

/*******************************************************************************/
CWsf_Ctrls_Control.prototype.OnUpdateCmdUI = function (sCmdId, CmdUI)
{
   return false;
}


/*******************************************************************************/
function CWsf_Ctrls_LayoutStack(ctrl)
{
   ctrl.Elem.style.overflow = "auto";
   if (g_App.IsIE) ctrl.Elem.style.overflowX = "hidden";
}

/*******************************************************************************/
CWsf_Ctrls_LayoutStack.prototype.LayoutChildren = function (ctrl)
{  
   // FireFox fix: it remembers the largest size of content and shows scrollbars
   // even if the content is shrinked
   
   if (g_App.IsGecko)
   {
      var sOldOverflow = ctrl.Elem.style.overflow;
      ctrl.Elem.style.overflow = 'hidden';
   }
   
   // Get the height of all fixed controls and # of stretch controls
   
   var nFixedH = 0;
   var nStretchCount = 0;
   
   for (var i=ctrl._children.length; i--;)
   {
      var o = ctrl._children[i];
      if (!o.IsVisible()) continue;
      
      if (o.GetStyle('stretch',false))
      {
         ++nStretchCount;
         o.Elem.style.overflow = "auto";
      }
      else
         nFixedH += o.GetHeight() + o.GetComputedStyle('marginTop',0) + o.GetComputedStyle('marginBottom',0);
   }
   
   // Layout

   var padding = ctrl.GetStyle('padding',0);
   var a = ctrl.GetClientSize();
   var w = a['width'] - padding*2;
   var h = a['height'] - padding*2;
   var y = padding;
   var x = padding;
   var nStretchH = Math.max(h - nFixedH, 0);
   
   if (nStretchCount > 0)
   {
      var nAvgStretchH = Math.floor(nStretchH / nStretchCount);
      var nLastStretchH = h - nAvgStretchH*(nStretchCount-1) - nFixedH;
   }
   
   var lastBottomMargin = 0;
   
   for (var i=0,n=ctrl._children.length; i < n; ++i)
   {
      var o = ctrl._children[i];
      if (!o.IsVisible()) continue;
      
      var margin = o.GetStyle('margin',0);
      var topMargin = Math.max(o.GetComputedStyle('marginTop',0) - lastBottomMargin, 0);
      var bottomMargin = o.GetComputedStyle('marginBottom',0);
      lastBottomMargin = bottomMargin;
      
      if (o.GetStyle('stretch',false))
      {
         h = (--nStretchCount ? nAvgStretchH : nLastStretchH);
         o.Move(x+margin, y+topMargin, w-2*margin, h-topMargin-bottomMargin);
      }
      else
      {
         h = o.GetHeight() + topMargin + bottomMargin;
         o.Move(x+margin, y+topMargin, w-2*margin, null);
      }
      
      y += h;
   }   
   
   // Firefox fix: restore overflow
   
   if (g_App.IsGecko)
   {
      ctrl.Elem.style.overflow = sOldOverflow;
   }
}


/*******************************************************************************/
function CWsf_Ctrls_LayoutFullsize(ctrl)
{
}

/*******************************************************************************/
CWsf_Ctrls_LayoutFullsize.prototype.LayoutChildren = function (ctrl)
{  
   // Get control to layout and pass the event to other controls
   
   var o = null;
   
   for (var i=0,n=ctrl.GetChildCount(); i<n; ++i)
   {
      var t = ctrl.GetChildByIdx(i);
      if (t.IsVisible())
      {
         if (t.GetStyle('stretch', false))
         {
            o = t;
         }
         else
         {
            t._ClearSizeCache();
            t.OnSize();
         }
      }
   }
   
   // Make the control fullsize
   
   if (o)
   {
      // FireFox fix: it remembers the largest size of content and shows scrollbars
      // even if the content is shrinked
      
      if (g_App.IsGecko && ctrl.Elem)
      {
         var sOldOverflow = ctrl.Elem.style.overflow;
         ctrl.Elem.style.overflow = 'hidden';
      }     

      // Resize
      
      var m = ctrl.GetStyle('padding',0);
      var a = ctrl.GetClientSize();
      o.Move(m,m, a['width']-m*2, a['height']-m*2);

      // Firefox fix: restore overflow
      
      if (g_App.IsGecko && ctrl.Elem)
      {
         ctrl.Elem.style.overflow = sOldOverflow;
      }
   }
}

/*****************************************************************************/
function CWsf_Web_Vocabulary(vocabulary)
{
   this.vocabulary = vocabulary;
}

/*****************************************************************************/
function W(id)
{
   a = id.split('.');
   return wsfVocabulary.vocabulary[a[0]][a[1]];
}

/*******************************************************************************/
function CWsf_Web_CallServerMethodHandler(fnOnSuccess, transport)
{
   g_App._activeServerMethodCall = this;
   
   this.fnOnSuccess = fnOnSuccess;
   this.response = transport.responseText.evalJSON();
   this.loadScriptIdx = 0;
   
   this._StateLoadNextScript();
}

/*******************************************************************************/
CWsf_Web_CallServerMethodHandler.prototype._StateLoadNextScript = function()
{
   if (this.loadScriptIdx == this.response.scripts.length) 
   {
      this._StateFinish();
      return;
   }
   
   // TODO: detect inline scripts
   
   var e = $(document.createElement('script'));
   e.observe(g_App.IsIE ? 'readystatechange':'load', this._StateLoadNextScript.bindAsEventListener(this));
   e.setAttribute('src', this.response.scripts[this.loadScriptIdx]); 
   e.setAttribute('type', 'text/javascript');
   document.body.appendChild(e); 

   ++this.loadScriptIdx;
}

/*******************************************************************************/
CWsf_Web_CallServerMethodHandler.prototype._StateFinish = function()
{
   for (var i=0; i < this.response.newCtrls.length; ++i)
   {
      var o = this.response.newCtrls[i];
      
      var parent = g_App.GetCtrlById(o.parentId);
      var e = document.createElement('div');
      parent.Elem.insertBefore(e, null);//parent.Elem.childNodes[0]);
      $(e).replace(o.html);

      eval(o.js);      
   }
   
   if (this.fnOnSuccess) this.fnOnSuccess(this.response.returnValue);
   
   g_App._activeServerMethodCall = null;
}

/**
* DD_roundies, this adds rounded-corner CSS in standard browsers and VML sublayers in IE that accomplish a similar appearance when comparing said browsers.
* Author: Drew Diller
* Email: drew.diller@gmail.com
* URL: http://www.dillerdesign.com/experiment/DD_roundies/
* Version: 0.0.2a -  preview 2008.12.26
* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_roundies/#license
*
* Usage:
* DD_roundies.addRule('#doc .container', '10px 5px'); // selector and multiple radii
* DD_roundies.addRule('.box', 5, true); // selector, radius, and optional addition of border-radius code for standard browsers.
* 
* Just want the PNG fixing effect for IE6, and don't want to also use the DD_belatedPNG library?  Don't give any additional arguments after the CSS selector.
* DD_roundies.addRule('.your .example img');
**/

eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('t K={16:\'K\',1L:G,1M:G,1d:G,2f:y(){u(D.2g!=8&&D.1N&&!D.1N[q.16]){q.1L=M;q.1M=M}17 u(D.2g==8){q.1d=M}},2h:D.2i,1O:[],1b:{},2j:y(){u(q.1L||q.1M){D.1N.2L(q.16,\'2M:2N-2O-2P:x\')}u(q.1d){D.2Q(\'<?2R 2S="\'+q.16+\'" 2T="#1P#2k" ?>\')}},2l:y(){t a=D.1k(\'z\');D.2m.1w.1Q(a,D.2m.1w.1w);u(a.12){2n{t b=a.12;b.1x(q.16+\'\\\\:*\',\'{1l:2U(#1P#2k)}\');q.12=b}2o(2p){}}17{q.12=a}},1x:y(a,b,c){u(1R b==\'1S\'||b===2V){b=0}u(b.2W.2q().1y(\'2X\')==-1){b=b.2q().2Y(/[^0-9 ]/g,\'\').1T(\' \')}H(t i=0;i<4;i++){b[i]=(!b[i]&&b[i]!==0)?b[C.1e((i-2),0)]:b[i]}u(q.12){u(q.12.1x){t d=a.1T(\',\');H(t i=0;i<d.1U;i++){q.12.1x(d[i],\'1l:2Z(K.1V.2r(q, [\'+b.1W(\',\')+\']))\')}}17 u(c){t e=b.1W(\'F \')+\'F\';q.12.1z(D.2s(a+\' {Q-1f:\'+e+\'; -30-Q-1f:\'+e+\';}\'));q.12.1z(D.2s(a+\' {-1A-Q-1m-1n-1f:\'+b[0]+\'F \'+b[0]+\'F; -1A-Q-1m-1X-1f:\'+b[1]+\'F \'+b[1]+\'F; -1A-Q-1Y-1X-1f:\'+b[2]+\'F \'+b[2]+\'F; -1A-Q-1Y-1n-1f:\'+b[3]+\'F \'+b[3]+\'F;}\'))}}17 u(q.1d){q.1O.31({\'2t\':a,\'2u\':b})}},2v:y(a){2w(32.33){I\'z.Q\':I\'z.34\':I\'z.1B\':q.1o(a);13;I\'z.2x\':q.1Z(a);13;I\'z.1p\':I\'z.2y\':I\'z.2z\':q.1o(a);13;I\'z.20\':a.18.z.20=(a.z.20==\'S\')?\'S\':\'35\';13;I\'z.21\':q.22(a);13;I\'z.1c\':a.18.z.1c=a.z.1c;13}},1o:y(a){a.14.23=\'\';q.2A(a);q.1Z(a);q.1C(a);q.1D(a);q.24(a);q.2B(a);q.22(a)},22:y(a){u(a.W.21.1y(\'36\')!=-1){t b=a.W.21;b=1g(b.37(b.25(\'=\')+1,b.25(\')\')),10)/2C;H(t v 1h a.x){a.x[v].1i.38=b}}},2A:y(a){u(!a.W){1q}17{t b=a.W}a.14.1p=\'\';a.14.1E=\'\';t c=(b.1p==\'2D\');t d=M;u(b.1E!=\'S\'||a.1F){u(!a.1F){a.J=b.1E;a.J=a.J.39(5,a.J.25(\'")\')-5)}17{a.J=a.26}t e=q;u(!e.1b[a.J]){t f=D.1k(\'3a\');f.1r(\'3b\',y(){q.1s=q.3c;q.1t=q.3d;e.1D(a)});f.3e=e.16+\'3f\';f.14.23=\'1l:S; 1j:27; 1m:-2E; 1n:-2E; Q:S;\';f.26=a.J;f.2F(\'1s\');f.2F(\'1t\');D.2G.1Q(f,D.2G.1w);e.1b[a.J]=f}a.x.Z.1i.26=a.J;d=G}a.x.Z.2H=!d;a.x.Z.1G=\'S\';a.x.1u.2H=!c;a.x.1u.1G=b.1p;a.14.1E=\'S\';a.14.1p=\'2D\'},1Z:y(a){a.x.1H.1G=a.W.2x},1C:y(a){t c=[\'N\',\'19\',\'1a\',\'O\'];a.P={};H(t b=0;b<4;b++){a.P[c[b]]=1g(a.W[\'Q\'+c[b]+\'U\'],10)||0}},1D:y(c){t e=[\'O\',\'N\',\'U\',\'V\'];H(t d=0;d<4;d++){c.E[e[d]]=c[\'3g\'+e[d]]}t f=y(a,b){a.z.1n=(b?0:c.E.O)+\'F\';a.z.1m=(b?0:c.E.N)+\'F\';a.z.1s=c.E.U+\'F\';a.z.1t=c.E.V+\'F\'};H(t v 1h c.x){t g=(v==\'Z\')?1:2;c.x[v].3h=(c.E.U*g)+\', \'+(c.E.V*g);f(c.x[v],M)}f(c.18,G);u(K.1d){c.x.1H.z.28=\'-3i\';u(1R c.P==\'1S\'){q.1C(c)}c.x.1u.z.28=(c.P.N-1)+\'F \'+(c.P.O-1)+\'F\'}},24:y(j){t k=y(a,w,h,r,b,c,d){t e=a?[\'m\',\'1I\',\'l\',\'1J\',\'l\',\'1I\',\'l\',\'1J\',\'l\']:[\'1J\',\'l\',\'1I\',\'l\',\'1J\',\'l\',\'1I\',\'l\',\'m\'];b*=d;c*=d;w*=d;h*=d;t R=r.2I();H(t i=0;i<4;i++){R[i]*=d;R[i]=C.3j(w/2,h/2,R[i])}t f=[e[0]+C.11(0+b)+\',\'+C.11(R[0]+c),e[1]+C.11(R[0]+b)+\',\'+C.11(0+c),e[2]+C.15(w-R[1]+b)+\',\'+C.11(0+c),e[3]+C.15(w+b)+\',\'+C.11(R[1]+c),e[4]+C.15(w+b)+\',\'+C.15(h-R[2]+c),e[5]+C.15(w-R[2]+b)+\',\'+C.15(h+c),e[6]+C.11(R[3]+b)+\',\'+C.15(h+c),e[7]+C.11(0+b)+\',\'+C.15(h-R[3]+c),e[8]+C.11(0+b)+\',\'+C.11(R[0]+c)];u(!a){f.3k()}t g=f.1W(\'\');1q g};u(1R j.P==\'1S\'){q.1C(j)}t l=j.P;t m=j.2J.2I();t n=k(M,j.E.U,j.E.V,m,0,0,2);m[0]-=C.1e(l.O,l.N);m[1]-=C.1e(l.N,l.19);m[2]-=C.1e(l.19,l.1a);m[3]-=C.1e(l.1a,l.O);H(t i=0;i<4;i++){m[i]=C.1e(m[i],0)}t o=k(G,j.E.U-l.O-l.19,j.E.V-l.N-l.1a,m,l.O,l.N,2);t p=k(M,j.E.U-l.O-l.19+1,j.E.V-l.N-l.1a+1,m,l.O,l.N,1);j.x.1u.29=o;j.x.Z.29=p;j.x.1H.29=n+o;q.2K(j)},2B:y(a){t s=a.W;t b=[\'N\',\'O\',\'19\',\'1a\'];H(t i=0;i<4;i++){a.14[\'1B\'+b[i]]=(1g(s[\'1B\'+b[i]],10)||0)+(1g(s[\'Q\'+b[i]+\'U\'],10)||0)+\'F\'}a.14.Q=\'S\'},2K:y(e){t f=K;u(!e.J||!f.1b[e.J]){1q}t g=e.W;t h={\'X\':0,\'Y\':0};t i=y(a,b){t c=M;2w(b){I\'1n\':I\'1m\':h[a]=0;13;I\'3l\':h[a]=0.5;13;I\'1X\':I\'1Y\':h[a]=1;13;1P:u(b.1y(\'%\')!=-1){h[a]=1g(b,10)*0.3m}17{c=G}}t d=(a==\'X\');h[a]=C.15(c?((e.E[d?\'U\':\'V\']-(e.P[d?\'O\':\'N\']+e.P[d?\'19\':\'1a\']))*h[a])-(f.1b[e.J][d?\'1s\':\'1t\']*h[a]):1g(b,10));h[a]+=1};H(t b 1h h){i(b,g[\'2y\'+b])}e.x.Z.1i.1j=(h.X/(e.E.U-e.P.O-e.P.19+1))+\',\'+(h.Y/(e.E.V-e.P.N-e.P.1a+1));t j=g.2z;t c={\'T\':1,\'R\':e.E.U+1,\'B\':e.E.V+1,\'L\':1};t k={\'X\':{\'2a\':\'L\',\'2b\':\'R\',\'d\':\'U\'},\'Y\':{\'2a\':\'T\',\'2b\':\'B\',\'d\':\'V\'}};u(j!=\'2c\'){c={\'T\':(h.Y),\'R\':(h.X+f.1b[e.J].1s),\'B\':(h.Y+f.1b[e.J].1t),\'L\':(h.X)};u(j.1y(\'2c-\')!=-1){t v=j.1T(\'2c-\')[1].3n();c[k[v].2a]=1;c[k[v].2b]=e.E[k[v].d]+1}u(c.B>e.E.V){c.B=e.E.V+1}}e.x.Z.z.3o=\'3p(\'+c.T+\'F \'+c.R+\'F \'+c.B+\'F \'+c.L+\'F)\'},1v:y(a){t b=q;2d(y(){b.1o(a)},1)},2e:y(a){q.1D(a);q.24(a)},1V:y(b){q.z.1l=\'S\';u(!q.W){1q}17{t c=q.W}t d={3q:G,3r:G,3s:G,3t:G,3u:G,3v:G,3w:G};u(d[q.1K]===G){1q}t e=q;t f=K;q.2J=b;q.E={};t g={3x:\'2e\',3y:\'2e\'};u(q.1K==\'A\'){t i={3z:\'1v\',3A:\'1v\',3B:\'1v\',3C:\'1v\'};H(t a 1h i){g[a]=i[a]}}H(t h 1h g){q.1r(\'3D\'+h,y(){f[g[h]](e)})}q.1r(\'3E\',y(){f.2v(e)});t j=y(a){a.z.3F=1;u(a.W.1j==\'3G\'){a.z.1j=\'3H\'}};j(q.3I);j(q);q.18=D.1k(\'3J\');q.18.14.23=\'1l:S; 1j:27; 28:0; 1B:0; Q:0; 3K:S;\';q.18.z.1c=c.1c;q.x={\'1u\':M,\'Z\':M,\'1H\':M};H(t v 1h q.x){q.x[v]=D.1k(f.16+\':3L\');q.x[v].1i=D.1k(f.16+\':3M\');q.x[v].1z(q.x[v].1i);q.x[v].3N=G;q.x[v].z.1j=\'27\';q.x[v].z.1c=c.1c;q.x[v].3O=\'1,1\';q.18.1z(q.x[v])}q.x.Z.1G=\'S\';q.x.Z.1i.3P=\'3Q\';q.3R.1Q(q.18,q);q.1F=G;u(q.1K==\'3S\'){q.1F=M;q.z.3T=\'3U\'}2d(y(){f.1o(e)},1)}};2n{D.3V("3W",G,M)}2o(2p){}K.2f();K.2j();K.2l();u(K.1d&&D.1r&&K.2h){D.1r(\'3X\',y(){u(D.3Y==\'3Z\'){t d=K.1O;t e=d.1U;t f=y(a,b,c){2d(y(){K.1V.2r(a,b)},c*2C)};H(t i=0;i<e;i++){t g=D.2i(d[i].2t);t h=g.1U;H(t r=0;r<h;r++){u(g[r].1K!=\'40\'){f(g[r],d[i].2u,r)}}}}})}',62,249,'||||||||||||||||||||||||||this|||var|if|||vml|function|style|||Math|document|dim|px|false|for|case|vmlBg|DD_roundies||true|Top|Left|bW|border||none||Width|Height|currentStyle|||image||floor|styleSheet|break|runtimeStyle|ceil|ns|else|vmlBox|Right|Bottom|imgSize|zIndex|IE8|max|radius|parseInt|in|filler|position|createElement|behavior|top|left|applyVML|backgroundColor|return|attachEvent|width|height|color|pseudoClass|firstChild|addRule|search|appendChild|webkit|padding|vmlStrokeWeight|vmlOffsets|backgroundImage|isImg|fillcolor|stroke|qy|qx|nodeName|IE6|IE7|namespaces|selectorsToProcess|default|insertBefore|typeof|undefined|split|length|roundify|join|right|bottom|vmlStrokeColor|display|filter|vmlOpacity|cssText|vmlPath|lastIndexOf|src|absolute|margin|path|b1|b2|repeat|setTimeout|reposition|IEversion|documentMode|querySelector|querySelectorAll|createVmlNameSpace|VML|createVmlStyleSheet|documentElement|try|catch|err|toString|call|createTextNode|selector|radii|readPropertyChanges|switch|borderColor|backgroundPosition|backgroundRepeat|vmlFill|nixBorder|100|transparent|10000px|removeAttribute|body|filled|slice|DD_radii|clipImage|add|urn|schemas|microsoft|com|writeln|import|namespace|implementation|url|null|constructor|Array|replace|expression|moz|push|event|propertyName|borderWidth|block|lpha|substring|opacity|substr|img|onload|offsetWidth|offsetHeight|className|_sizeFinder|offset|coordsize|1px|min|reverse|center|01|toUpperCase|clip|rect|BODY|TABLE|TR|TD|SELECT|OPTION|TEXTAREA|resize|move|mouseleave|mouseenter|focus|blur|on|onpropertychange|zoom|static|relative|offsetParent|ignore|background|shape|fill|stroked|coordorigin|type|tile|parentNode|IMG|visibility|hidden|execCommand|BackgroundImageCache|onreadystatechange|readyState|complete|INPUT'.split('|'),0,{}))
function CWsf_Ctrls_View(p) { CWsf_Ctrls_Control.apply(this, [p]); } Object.extend(CWsf_Ctrls_View.prototype, CWsf_Ctrls_Control.prototype);


/*******************************************************************************/
function CWsf_Ctrls_ViewHtml(Params)
{
   CWsf_Ctrls_Control.apply(this, [Params]);

   Event.observe(document.body, 'activate', this._OnFocus.bindAsEventListener(this));
   
   CWsf_Ctrls_ViewHtml.prototype._instance = this;
}

Object.extend(CWsf_Ctrls_ViewHtml.prototype, CWsf_Ctrls_Control.prototype);

/*******************************************************************************/
CWsf_Ctrls_ViewHtml.prototype.Init = function ()
{
   CWsf_Ctrls_Control.prototype.Init.apply(this);

   if (this._focusedCtrl) 
   {   
      if (!this._focusedCtrl.Focus()) this._focusedCtrl = null;
   }
}

/*******************************************************************************/
CWsf_Ctrls_ViewHtml.prototype._OnFocus = function (ev)
{
   // NOTE: IE: Do not pass newly focused controls back to improve focus-stealing resistance :-)
   // Optimize when we know how
   if (!g_App.IsIE) this._focusedCtrl = g_App.GetCtrlById(Event.element(ev).id);
}

/*******************************************************************************/
CWsf_Ctrls_ViewHtml.prototype.GetFocus = function()
{
   return this._focusedCtrl;
}



function CWeb_ViewMainFrame(serverState)
{
   CWsf_Ctrls_ViewHtml.call(this, serverState);
   DD_roundies.addRule('.topMenu li', '5px 5px 0 0', true); 
}

Wsf.Extend(CWeb_ViewMainFrame, CWsf_Ctrls_ViewHtml);

/*******************************************************************************/
function CWsf_Ctrls_Menu(Params)
{
   CWsf_Ctrls_Control.apply(this, [Params]);

   this.aItemElems = [];
   this.Elem.descendants().each(this._DecorateElem.bind(this));
   this.isAnyItemEnabled = false;
   this.isForceUpdateUIWhenInvisible = false;
}

Object.extend(CWsf_Ctrls_Menu.prototype, CWsf_Ctrls_Control.prototype);

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype._DecorateElem = function (e)
{
   if (e.tagName != "LI") return;

   this.aItemElems.push(e);

   var a = e.id.split('.');
   e.sCmdId = a.length == 2 ? a[1] : null;

   if (this._isClientExpandMode)
   {
      if (e.sCmdId != '' && e.hasClassName('clickable'))
      {
         e.observe('click', this.OnClickItem.bindAsEventListener(this, e));
      } 

      e.observe('mouseover', this.LI_OnMouseOver.bindAsEventListener(this, e));
      e.observe('mouseout', this.LI_OnMouseOut.bindAsEventListener(this, e));   
   }
}

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype._GetControlState = function ()
{
   var a = CWsf_Ctrls_Control.prototype._GetControlState.apply(this);

   a.aSelIDs = [];
   
   for (var i=this.aItemElems.length; i--;)
   {
      var e = this.aItemElems[i];
      if (e.hasClassName('sel')) a.aSelIDs.push(e.id.split('.')[1]);
   }
      
   return a;
}

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype.UpdateUI = function ()
{
   if (!this._isCmdMode || (!this.isForceUpdateUIWhenInvisible && !this.IsVisible())) return;

   var CmdUI = 
   { 
      IsEnabled : true,
      IsChecked : false,
      Enable: function (IsEnabled) { this.IsEnabled = IsEnabled; },
      Check: function (IsChecked) { this.IsChecked = IsChecked; }
   };
   
   this.isAnyItemEnabled = false;
                                          
   for (var i=this.aItemElems.length; i--;)
   {
      var e = this.aItemElems[i];
      var sCmdId = e.id.split('.')[1];
      CmdUI.IsEnabled = true;
      CmdUI.IsChecked = false;
      
      g_App.InvokeUpdateCmd(this._GetCmdTarget(), sCmdId, CmdUI);

      if (CmdUI.IsEnabled)
      {
         this.isAnyItemEnabled = true;
         e.removeClassName('disabled'); 
      }
      else
         e.addClassName('disabled'); 
         
      if (CmdUI.IsChecked)
         e.addClassName('checked'); 
      else
         e.removeClassName('checked');          
   }
}

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype.IsAnyItemEnabled = function()
{
   return this.isAnyItemEnabled;
}

/*****************************************************************************/
/*
/* SELECTION
/*
/*****************************************************************************/

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.SelectItem = function (id, isSelect)
{
   for (var i=this.aItemElems.length; i--;)
   {
      var e = this.aItemElems[i];
      
      if (id == e.id.split('.')[1])
      {
         if (isSelect)
            e.addClassName('sel');
         else
            e.removeClassName('sel');
         break;
      }
   }
}

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.GetSelId = function ()
{
   for (var i=this.aItemElems.length; i--;)
   {
      var e = this.aItemElems[i];
      
      if (e.hasClassName('sel')) return e.id.split('.')[1];
   }
   
   return null;
}

/*****************************************************************************/
/*
/* EVENTS
/*
/*****************************************************************************/

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.OnClickItem = function (ev, LI)
{
   Event.stop(ev);
   
   if ($(LI).hasClassName("disabled")) return;
   if ($(LI).hasClassName("expandable")) return;
   
   if (this.IsContextMenu) this.HideContextMenu();
   
   // Notify

   if (this.fnOnClickCallback) {
      this.fnOnClickCallback(LI.sCmdId);
   }
   else if (this._isCmdMode) {
      g_App.InvokeCmd(this._GetCmdTarget(), LI.sCmdId, {});
   }
}

/*****************************************************************************/
/*
/* CONTEXT MENU
/*
/*****************************************************************************/

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype.TrackContextMenu = function(nX, nY, fnOnClickCallback)
{
   this.fnOnClickCallback = fnOnClickCallback;
   this.IsContextMenu = true;
   this.IsWithin = false;
   
   this.Elem.style.left = nX + "px";
   this.Elem.style.top = nY + "px";
   this.Show(true);
   this.Focus();

   this.fnTCMOnClickDoc = this.TCM_OnClickDoc.bindAsEventListener(this);
   this.fnTCMOnClickMenu = this.TCM_OnClickMenu.bindAsEventListener(this);
   this.fnTCMOnKeyDown = this._TCM_OnKeyDown.bindAsEventListener(this);
   
   Event.observe(document, "mousedown", this.fnTCMOnClickDoc);
   Event.observe(this.Elem, "mousedown", this.fnTCMOnClickMenu);         
   Event.observe(this.Elem, "keydown", this.fnTCMOnKeyDown);         
   
   this.UpdateUI();
}

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype.HideContextMenu = function()
{
   Event.stopObserving(document, "mousedown", this.fnTCMOnClickDoc);
   Event.stopObserving(this.Elem, "mousedown", this.fnTCMOnClickMenu);
   Event.stopObserving(this.Elem, "keydown", this.fnTCMOnKeyDown);
   this.Show(false);
   this.IsContextMenu = false;
}

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.TCM_OnClickDoc = function (event)
{
   if (!this.IsWithin) this.HideContextMenu();
   this.IsWithin = false;
}

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.TCM_OnClickMenu = function (event)
{
   this.IsWithin = true;
}

/*******************************************************************************/
CWsf_Ctrls_Menu.prototype._TCM_OnKeyDown = function (ev)
{
   if (ev.keyCode == Event.KEY_ESC)
   {
      this.HideContextMenu();
   }
}

/*******************************************************************************/
/*
/* Expanding subitems
/*
/*******************************************************************************/

/*****************************************************************************/
function WsfCtrlMenu_DelayedHide(LI)
{
   var SubItemsUL = $(LI).down().next('ul');
   var TitleDIV = $(LI).down();
   TitleDIV.removeClassName("exp");
   SubItemsUL.hide();

   window.clearTimeout(SubItemsUL.nTimeID);
   SubItemsUL.nTimeID = null;
}

/*****************************************************************************/
function WsfCtrlMenu_DelayedShow(LI)
{
   var SubItemsUL = $(LI).down().next('ul');
   var TitleDIV = $(LI).down();
   TitleDIV.addClassName("exp");
   SubItemsUL.show();

   window.clearTimeout(SubItemsUL.nTimeID);
   SubItemsUL.nTimeID = null;
}

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.LI_OnMouseOver = function (ev, LI)
{
   if (!LI.hasClassName("clickable") || LI.hasClassName("disabled")) return;
   LI.addClassName("hover");

   var SubItemsUL = LI.down('ul');
   if (!SubItemsUL) return;
   
   if (SubItemsUL.nTimeID)
   {
      window.clearTimeout(SubItemsUL.nTimeID);
      SubItemsUL.nTimeID = null;
   }   
   else
   {
      SubItemsUL.nTimeID = window.setTimeout(function() { WsfCtrlMenu_DelayedShow(LI); }, 250);
   }
}

/*****************************************************************************/
CWsf_Ctrls_Menu.prototype.LI_OnMouseOut = function (ev, LI)
{
   if (LI.hasClassName("disabled")) return;
   LI.removeClassName("hover");

   var SubItemsUL = LI.down('ul');
   if (!SubItemsUL) return;
   
   if (SubItemsUL.nTimeID)
   {
      window.clearTimeout(SubItemsUL.nTimeID);
      SubItemsUL.nTimeID = null;
   }   
   else
   {
      SubItemsUL.nTimeID = window.setTimeout(function() { WsfCtrlMenu_DelayedHide(LI); }, 500);
   }
}

var wsfVocabulary = new CWsf_Web_Vocabulary({"Web" : {"NEWS_TITLE" : "aktuality","PUBLIC_DATE" : "Publikováno","MORE" : "Více >>","SKIP_NAVIGATION" : "Přeskočit navigaci"},"Wsf_Ctrls" : {"WSF_ROWS_PER_PAGE" : "Řádků na stránce","WSF_PAGE" : "Stránka","WSF_PREV_PAGE" : "< Předchozí","WSF_NEXT_PAGE" : "Další >","WSF_THUMBS" : "Náhledy","SORT_BY" : "Seřadit podle","WSF_LOCATION" : "Umístění"},"Wsf" : {"MONTH_1" : "leden","MONTH_2" : "únor","MONTH_3" : "březen","MONTH_4" : "duben","MONTH_5" : "květen","MONTH_6" : "červen","MONTH_7" : "červenec","MONTH_8" : "srpen","MONTH_9" : "září","MONTH_10" : "říjen","MONTH_11" : "listopad","MONTH_12" : "prosinec","MONTH_3LTRS_1" : "Led","MONTH_3LTRS_2" : "Úno","MONTH_3LTRS_3" : "Bře","MONTH_3LTRS_4" : "Dub","MONTH_3LTRS_5" : "Kvě","MONTH_3LTRS_6" : "Čer","MONTH_3LTRS_7" : "Čev","MONTH_3LTRS_8" : "Srp","MONTH_3LTRS_9" : "Zář","MONTH_3LTRS_10" : "Říj","MONTH_3LTRS_11" : "Lis","MONTH_3LTRS_12" : "Pro","DAY2_0" : "Po","DAY2_1" : "Út","DAY2_2" : "St","DAY2_3" : "Čt","DAY2_4" : "Pá","DAY2_5" : "So","DAY2_6" : "Ne","CANCEL" : "Storno","APPLY" : "Použít","INVALID_ARGUMENT" : "Neplatný parametr"}});
