// main.js

String.prototype.trim = function() {
   return this.replace(/(^\s+|\s+$)/g, "");
}

//var undefined;

// dummy for mozilla Firebug plugin logging
if (typeof(console) == 'undefined') {
  console = {
    log : function(str) {},
    group : function(str) {},
    groupEnd : function() {},
    trace : function() {}
  }
}

// dummy for MochiKit to work in FF
if (typeof(log) == 'undefined') {
  log = function (msg) {
    console.log(msg);
  }
}

if (typeof(SW) == 'undefined') {
  SW = {
    _modules : {},
    loadStatus : {'loading' : 1, 'ok' : 2},

    _initLoadedModules : function() {
      var scripts = document.getElementsByTagName("script");

      SW._modules = {};
      for (var i = 0; i < scripts.length; i++) {
        var src = scripts[i].getAttribute("src");
        if (!src) continue;
        SW._modules[src] = {'status' : SW.loadStatus.ok};
      }
    },

    myimport : function(uri) {
      var request = false;

      if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        request = new XMLHttpRequest();
        //request.overrideMimeType("text/xml");
      } else if (window.ActiveXObject) { // IE
        try {
          request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
          try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e) {}
        }
      }

      if (!request) {
        console.log("Giving up. Cannot create an XMLHTTP instance.");
        return;
      }


      request.onreadystatechange = function () {
        if (request.readyState != 4) return;
        if (request.status == 200) {
          //document.write('<script type="text/javascript">'+request.responseText+'</script>');

          var script = document.createElement('script');
          script.type = 'text/javascript';
          //script.src = uri;
          //script.innerHTML = request.responseText;
          var theData = document.createTextNode(request.responseText);
          //script.appendChild(theData);
          //document.getElementsByTagName('head')[0].appendChild(script);

document.write('<script type="text/javascript">'+request.responseText+'</script>');

          SW._modules[uri] = {'status' : SW.loadStatus.ok};
          //console.log('loaded '+uri);
        }
      };
      request.open("GET", uri, true);
      request.send(null);
    },

    _import : function (uri) {
      if (uri in SW._modules) return;
      SW._modules[uri] = {'status' : SW.loadStatus.loading};
      //setTimeout('SW._import("'+uri+'")', 1); // do in background
      //console.log('import '+uri);
      SW._import(uri);
    }

  }
}
SW._initLoadedModules();

SW.Loader = function(waitObjects) {
  this.waitObjects = waitObjects;
}

SW.Loader.prototype = {
  objectsLoaded : function() {
    var waitObjects = this.waitObjects;
    if (typeof(waitObjects) == 'undefined') return true;
    if (typeof(waitObjects) == 'string') waitObjects = [waitObjects];
    for (var i=0; i<waitObjects.length; i++) {
      if (!eval(waitObjects[i])) return false;
    }
    return true;
  },

  execute : function(callback) {
    //console.log('SW.execute '+callback);
    var stillwait = false;
    for (m in SW._modules) {
      if (SW._modules[m].status != SW.loadStatus.ok) {
        stillwait = true;
        break;
      }
    }
    if (stillwait || !callback || !this.objectsLoaded() || !SW.Signal) {
      var self = this;
      //console.log('waiting '+callback);
      setTimeout(function () {self.execute(callback);}, 100);
    } else {
      //console.log('exec '+callback);
      SW.Signal.addLoadEvent(callback);
    }
  }
}

SW.update = function (self, obj/*, ...*/) {
  if (self === null) self = {};
  for (var i = 1; i < arguments.length; i++) {
    var o = arguments[i];
    if (typeof(o) != 'undefined' && o !== null) {
      for (var k in o) {
        if (o[k] === null) o[k] = {};
        self[k] = o[k];
      }
    }
  }
}

SW.findIdentical = function (lst, value, start/* = 0 */, /* optional */end) {
  if (typeof(end) == "undefined" || end == null) {
    end = lst.length;
  }
  if (typeof(start) == "undefined" || start == null) {
    start = 0;
  }
  for (var i = start; i < end; i++) {
    if (lst[i] === value) {
      return i;
    }
  }
  return -1;
}

SW.msg = function () {
  if (!arguments.length) return "";
  var msg = arguments[0];
  if (locale[arguments[0]] != undefined) msg = locale[arguments[0]];
  var list = msg.split('$');
  var trans = list[0];
  for (var i=1; i<list.length; i++) {
    var m = /^(\d+)(.*)/.exec(list[i]);
    if (m == null) trans += list[i];
    else {
      var arg = arguments[m[1]];
      trans += arg + m[2];
    }
  }
  return trans;
}

SW.isIE = function () {
  return 'Microsoft Internet Explorer' == navigator.appName
}


SW.selectCountry = function (obj, country) {
  for (var i = 0; i < obj.length; i++) {
    if (obj[i].value != country) continue;
    obj.options[i].selected = true;
    break;
  }
}

SW.changeRatesPeriodPrices = function (obj, planID, digits, dec_sep, thousand_sep) {
	if (null == obj) return;
	if (!obj.value.length) return;
	 SW.Async.sendXMLHttpRequest('?info=planrate&PeriodID='+obj.value+'&PlanID='+planID,  function (str_rates_prices) {
	      var rates_prices = eval(str_rates_prices);
	      if (!rates_prices.length) return;
	    	  for (var i=0; i<rates_prices.length; i++) {
	    		  var obj_price_id = 'price_' + rates_prices[i].resourceCategoryID + '_' + rates_prices[i].resourceID;
	    		  var obj_price = document.getElementById(obj_price_id);
	    		  if (obj_price) {
	    			  var price_val = Number(rates_prices[i].extendedPrice).toFixed(digits);
	    			  if (isNaN(price_val)) {
	    				  obj_price.innerHTML = rates_prices[i].extendedPrice;
	    				  continue;
	    			  }   
	    			price_val = addSeparators(price_val, dec_sep, thousand_sep);
	    			obj_price.innerHTML = price_val;
	    		  }	  
	    	  }
	    });
}


SW.changeStateList = function (obj_country, obj_state, state, e) {
  if (!obj_country.options.length) return;
  if (null == obj_state) return;
  var countryCode = obj_country.options[obj_country.selectedIndex].value;

    // do not use SCRIPT_DIR as we can not determine it during synchronization and JS compression
    SW.Async.sendXMLHttpRequest('?info=statebook&CountryID='+countryCode,  function (str_states) {
      var states = eval(str_states);
      obj_state.length = 0;
      if (states.length) {
        obj_state[0] = new Option(locale["MAKE_SELECTION"], "");
        obj_state[0].selected = true;
        for (var i = 0; i < states.length; i++) {
          obj_state[i+1] = new Option(states[i].value, states[i].code);
          if (state.length && state == states[i].code) obj_state[i+1].selected = true;
        }
      }
      else {
        obj_state[0] = new Option(str_notApplicable, "");
      }

      if (obj_state.__span) {
        SW.Combo.populate(obj_state, obj_state.__span, obj_state.__ul);
      }

    }, e);

}

SW.refreshBasket = function (obj_payTool,e) {
  if (null == obj_payTool) return;
  var payToolID = obj_payTool.options[obj_payTool.selectedIndex].value;
  var paySystem = obj_payTool.options[obj_payTool.selectedIndex].attributes["system"].value;
  // do not use SCRIPT_DIR as we can not determine it during synchronization and JS compression
  SW.Async.sendXMLHttpRequest('?info=refreshbasket&PaySystemID='+paySystem,  function (str_basket) {
//      alert( str_basket );
      var basket = eval(str_basket);
      var hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;

      if (!hasInnerText){ // this is not IE
        document.getElementById("totalOrderDIV").textContent = basket[0].ordertotal;
        document.getElementById("totalTaxDIV").textContent = basket[0].taxtotal;
        document.getElementById("TotalsExtraChargeDiv").textContent = basket[0].handlFee;
      }else{ // this is IE
        document.getElementById("totalOrderDIV").innerText = basket[0].ordertotal;
        document.getElementById("totalTaxDIV").innerText = basket[0].taxtotal;
        document.getElementById("TotalsExtraChargeDiv").innerText = basket[0].handlFee;
      }

//      alert( basket[0].handlFee );

      if( basket[0].handlFee > 0 ){
        document.getElementById("TotalsExtraCharge").style.display = '';
        document.getElementById("HandlingFeeWarning").style.display = '';
      }else{
        document.getElementById("TotalsExtraCharge").style.display = 'none';
        document.getElementById("HandlingFeeWarning").style.display = 'none';
      }
  }, e);
}

function include(uri) {
//   SW.myimport(uri);

  var scripts = document.getElementsByTagName("script");

  var allScripts = {};
  for (var i = 0; i < scripts.length; i++) {
    var src = scripts[i].getAttribute("src");
    if (!src) continue;
    allScripts[src] = true;
  }

  if (uri in allScripts) return;

//   document.write('<script src="' + uri + '" type="text/javascript"></script>');
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = uri;
  document.getElementsByTagName('head')[0].appendChild(script);

  SW._modules[uri] = {'status' : SW.loadStatus.ok};
}


function loader(callback, waitObjects) {
  var l = new SW.Loader(waitObjects);
  l.execute(callback);
}


function addSeparators(nStr, decimalSep, thousandsSep)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? decimalSep + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1) && thousandsSep) {
		x1 = x1.replace(rgx, '$1' + thousandsSep + '$2');
	}
	return x1 + x2;
}

//include_once("../js/MochiKit/MochiKit.js");
//include("../js/firebug/firebug.js");

// include("../js/signal.js");
// include("../js/validate.js");
// include("../js/dom.js");
// include("../js/async.js");
// include("../js/window.js");
// include("../js/combo.js");
// include("../js/widget.js");
// include("../js/spin.js");


var countDisplay = 0;

SW.Display = function (block, showOrHide, disableWhenHidden) {
  block = SW.DOM.getElement(block);
  var _disabled = false;
  if (showOrHide) {
    block.style.display = "block";
  } else {
    block.style.display = "none";
    _disabled = true;
  }
  if (disableWhenHidden) {
    var inputs = block.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
      inputs[i].disabled = _disabled;
    }
    var selects = block.getElementsByTagName('select');
    for (var i = 0; i < selects.length; i++) {
      selects[i].disabled = _disabled;
    }
    var textareas = block.getElementsByTagName('textarea');
    for (var i = 0; i < textareas.length; i++) {
      textareas[i].disabled = _disabled;
    }
  }
}

function Display(id, usestatus, setstatus) {
  switch(usestatus) {
    case false: {
      var obj = document.getElementById(id);
      if (obj != null) {
        var status = document.getElementById(id).style.display;
        if (status == "none") {
          document.getElementById(id).style.display = "block";
          countDisplay += 1;
        } else {
          document.getElementById(id).style.display = "none";
          countDisplay -= 1;
        }
      }
      break;
    }
    case true: {
      var obj = document.getElementById(id);
      if (obj != null) {
        if(setstatus) {
          document.getElementById(id).style.display = "block";
        } else {
          document.getElementById(id).style.display = "none";
        }
      }
    } break;
    default:
      break;
  }
}


// plan_period.tpl
function InnerTextIDiv(idselect, id) {
  var str;
  var obj = document.getElementById(id);

  if (typeof idselect == "string") {
    var idselect = document.getElementById(idselect);
  }

  if (obj != null && typeof idselect == "object" && idselect != null) {
    var index = idselect.selectedIndex;
    if (index >= 0) {
      //str = idselect.options[index].label;
      str = idselect.options[index].getAttribute("description");
      if(str != null && str.length > 0) {
        document.getElementById(id).innerHTML = ""+str+"";
      }
    }
  }
}


function AddHiddenFields(obj, nameFields, valueFields) {
  if(obj != null && typeof obj == "object") {
    var newElement;
    var newElemValue = valueFields;
    if(typeof valueFields == "string" && valueFields.indexOf("%0A") != -1){
      newElement = document.createElement("textarea");
      newElement.style.visibility = "hidden";
      newElemValue = decodeURIComponent(newElemValue.replace(/\+/g, '%20'));
    } else {
      newElement = document.createElement("input");
      newElement.type = "hidden";
    }
    newElement.name = ""+nameFields+"";
    newElement.value = ""+newElemValue+"";
    obj.appendChild(newElement);
  }
}

function confirmRemove() {
  return confirm(locale["JAVASCRIPT_ALERT_REMOVE_FROM_BASKET"]);
}

var win=null;
function NewWindow(mypage,myname,w,h,scroll,pos){
  if(pos=="random"){LeftPosition=(screen.width)?Math.floor(Math.random()*(screen.width-w)):100;TopPosition=(screen.height)?Math.floor(Math.random()*((screen.height-h)-75)):100;}
  if(pos=="center"){LeftPosition=(screen.width)?(screen.width-w)/2:100;TopPosition=(screen.height)?(screen.height-h)/2:100;}
  else if((pos!="center" && pos!="random") || pos==null){LeftPosition=0;TopPosition=20}
  settings='width='+w+',height='+h+',top='+TopPosition+',left='+LeftPosition+',scrollbars='+scroll+',location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=no';
  win=window.open(mypage,myname,settings);
}


// EditGates/searchlightning.tpl
function InsertValueInField(Value, Name, Prefix) {
  var obj = document.getElementsByName(Name);
  var objByName = obj[Name];
  if (obj != null && typeof obj == "object") {
    if (typeof objByName["defaultPrefix"] == "undefined") {
      if (Name == "URL_INPUT") {
        var str = "http://www." + Prefix + Value;
      } else {
        var str = Prefix + Value;
      }
    } else {
      var str = objByName["defaultPrefix"] + Prefix + Value;
    }
    obj[Name].value = str;
  }
}

// EditGates/searchlightning.tpl
function ValidateURL(Name) {
  var obj = document.getElementsByName(Name);
  if (obj != null && typeof obj == "object") {
    var value = obj[0].value;
    var arrayOfSplit = value.split(".");
    var lengthOfArray = arrayOfSplit.length;
    var error = false;
    if (lengthOfArray <= 1) {
      window.alert(locale["JAVASCRIPT_ERROR_INVALID_DATA"]);
      obj[0].style.backgroundColor='#ffd9d9';
      error = true;
    } else {
      var lastZone = arrayOfSplit[lengthOfArray-1];
      if (lastZone.length <= 1 || lastZone.length > 4) {
        window.alert(locale["JAVASCRIPT_ERROR_INVALID_DATA"]);
        obj[0].style.backgroundColor='#ffd9d9';
        error = true;
      }
    }
    if (!error) {
      obj[0].style.backgroundColor='#FFFFFF';
      return true;
    } else {
      return false;
    }
  } else {
    return true;
  }
}


// ratedomain.tpl
function AscDisabling(current) {
  try {
    var ShowAlert = false;
    var objdomainlist = document.getElementById("domainlist");

    if (objdomainlist != null && typeof objdomainlist == "object") {
      var checkbox = objdomainlist.getElementsByTagName("input");
      for(var i = 0; i < checkbox.length; i++) {
        if (checkbox[i].getAttribute("typecontrol") == "rate") {
          if (checkbox[i].checked) {
          } else {
            ShowAlert  = true;
          }
        }
      }
    }

    if (ShowAlert && AscDisabling.alreadyCall == undefined) {
      alreadyAlert = true;
      var result  = confirm(locale["JAVASCRIPT_ALERT_DISABLING_PERFECT_PRIVACY"]);
      AscDisabling.alreadyCall = true;

      if (result) {
        current.checked = false;
      } else {
        current.checked = true;
      }
    }
  } catch(err)  {

  }

}

function sendGet(varArray, /*optional*/ actionURL) {
  for (var i=0; i < varArray.length-1; i+=2) {
    if (actionURL.indexOf('?') == -1) actionURL += '?';
    else actionURL += '&';
    actionURL += varArray[i] + '=' + encodeURIComponent(varArray[i+1]);
  }
  window.location.href = actionURL;
}

function post(varArray, /*optional*/ actionURL, /*optional*/ redirectMethod) {
  var form = document.createElement("form");
  if (null != actionURL) form.action = actionURL;
  else form.action = self.location;
  if(redirectMethod) {
    form.method = redirectMethod;
  } else {
    form.method = "post";
  }

  if (form.method.toLowerCase() == 'get') {
    sendGet(varArray, actionURL);
    return false;
  }

  for (var i=0; i < varArray.length-1; i+=2) {
    AddHiddenFields(form, varArray[i], varArray[i+1]);
  }

  document.body.appendChild(form);
  form.submit();
  
  return false;
}


SW._BrowserInit = function () {
  var b = navigator.appName;
  this.name = b;
  if (b.indexOf('Netscape') != -1) this.b = "ns";
  else if ((b=="Opera") || (navigator.userAgent.indexOf("Opera")>0)) this.b = "opera";
  else if (b=="Microsoft Internet Explorer") this.b="ie";
  if (!b) {this.b="invalid"; this.invalid=true;}
  this.version = navigator.appVersion;
  this.v = parseInt(this.version);
  this.ns = (this.b=="ns" && this.v>=4);
  this.ns4 = (this.b=="ns" && this.v==4);
  this.ns6 = (this.b=="ns" && this.v==5);
  this.ie = (this.b=="ie" && this.v>=4);
  this.ie4 = (this.version.indexOf('MSIE 4')>0);
  this.ie5 = (this.version.indexOf('MSIE 5')>0);
  this.ie55 = (this.version.indexOf('MSIE 5.5')>0);
  this.ie6 = (this.version.indexOf('MSIE 6.0')>0);
  this.opera = (this.b=="opera");
  this.dom = (document.createElement && document.appendChild && document.getElementsByTagName) ? true : false;
  this.def = (this.ie || this.dom); // most used browsers, for faster if loops
  var ua = navigator.userAgent.toLowerCase();
  if (ua.indexOf("win")>-1) this.platform="win32";
  else if (ua.indexOf("mac")>-1) this.platform="mac";
  else this.platform="other";
}
SW.Browser = new SW._BrowserInit();

function logDump(obj) {
  for (prop in obj) {
    try {log(prop+" => "+obj[prop]);}
    catch (ignore) {}

    if (typeof(obj[prop]) == 'object') {
      for (prop2 in obj[prop]) {
        try {log("  |- "+prop2+" => "+obj[prop][prop2]);}
        catch (ignore) {}
      }
    }
  }
}

function logDumpDOM(obj, level) {
  if (!level) level = 0;
  var padding = "";
  for (var i=0; i<level; i++) padding += "    ";

  if (obj.nodeType == 2 &&
      (obj.nodeValue == null || obj.nodeValue.length == 0)) return;

  if (obj.nodeName) {
    nodevalue = "";
    if (obj.nodeValue != null) nodevalue = " = "+obj.nodeValue;
    log(padding+obj.nodeName+nodevalue);
  }
  if (obj.nodeType == 1) {
    log(padding+"attributes array("+obj.attributes.length+") {");
    for (var i=0; i<obj.attributes.length; i++) logDump(obj.attributes[i], level+1);
    log(padding+"}");
  }
  if (obj.length) {
    log(padding+"array("+obj.length+") {");
    for (var i=0; i<obj.length; i++) logDump(obj[i], level+1);
    log(padding+"}");
  }

}

//SW.Signal.addLoadEvent(function (e) {logger.debuggingBookmarklet();});
//createLoggingPane(true);

if (!SW.App) SW.App = {}

SW.App.PlanRate = {
  _run : false,
  parents : new Array(),

  suit : function (wrapElem) {
    if (SW.App.PlanRate._run) return;
    SW.App.PlanRate._run = true;
    var me = SW.App.PlanRate;

    var tbodies = SW.DOM.getElementsByTagName("tbody", wrapElem);
    for (var i=tbodies.length-1; i >= 0; i--) {
      var m = /^planRateChild(\d+)(_\d+)?$/.exec(tbodies[i].id);
      if (m) me.suitChildren(wrapElem, m[1]);
    }

//     var texts = SW.DOM.getElementsByTagName("input", wrapElem);
//     for (var i=0; i < texts.length; i++) {
//       if (texts[i].getAttribute("type").toLowerCase() == "text" &&
//           texts[i].getAttribute("swWidgetType").toLowerCase() == "spin") {
//         SW.Widget.Spin.convert
//       }
//     }

    var inputs = SW.DOM.getElementsByTagName("input", wrapElem);
    for (i=0; i < inputs.length; i++) {
      var m = /^useExtRate_\d*_\d*$/.exec(inputs[i].id);
      if (inputs[i].type == 'checkbox' && m) {
        SW.Signal.connect(inputs[i], 'onclick', null, me.toggleNumbers);
      }

      var re = new RegExp('ExtRateAmount\\[\\d+\\]\\[_?\\d+_?\\]');
      if (re.exec(inputs[i].name) &&
          inputs[i].getAttribute('swWidgetType') == 'spin') {
        SW.Signal.connect(inputs[i], 'onchange',
                          null, me.positiveNumberIndicate);
        SW.Signal.dispatchEvent(inputs[i], 'onchange');
      }
      if (re.exec(inputs[i].name) &&
          (inputs[i].type == 'checkbox' || inputs[i].type == 'radio')) {
        if(inputs[i].type == 'radio' && inputs[i].value == '_0_') {
          var tbodies_matched = new Array();
          SW.App.PlanRate.addEventForRadio(tbodies_matched, inputs[i]);
        } else if(inputs[i].type == 'radio') {
          var radio_value = inputs[i].value; 
          radio_value = radio_value.replace(/_/g, "");
          var no_childs_for_radio = true;
          for (var ii=tbodies.length-1; ii >= 0; ii--) {
            var m = /^planRateChild(\d+)(_\d+)?$/.exec(tbodies[ii].id);
            if (m && m[1] == radio_value) {
              no_childs_for_radio = false;
              break;
            }
          }
          if(no_childs_for_radio) {
            var tbodies_matched = new Array();
            SW.App.PlanRate.addEventForRadio(tbodies_matched, inputs[i]);
          }
        }
        //SW.Signal.dispatchEvent(inputs[i], 'onclick');
      }
    }
  },

  addEventForRadio : function (tbodies_matched, parent) {
    // for 'none' in optional rates we need to connect event such way
    SW.Signal.connect(parent, 'onclick', null, function (e) {
      SW.App.PlanRate.toggleChildren(tbodies_matched, !parent.checked, parent);
    });
  },

  suitChildren : function (wrapElem, id) {
    //console.log('SW.App.PlanRate.suitChildren #'+id);
    var inputs = SW.DOM.getElementsByTagName('input', wrapElem);
    var parent = undefined;
    for (var i=0; i<inputs.length; i++) {
      var re = new RegExp('\\[\\d+\\]\\[_'+id+'_\\]');
      //var re2 = /useExtRate_\d+_\d+/
      var re2 = new RegExp('useExtRate_\\d+_'+id);
      if (re.exec(inputs[i].name) || re2.exec(inputs[i].name)) {
        parent = inputs[i];
        break;
      }
      if(inputs[i].getAttribute("type").toLowerCase() == "radio") {
        if(inputs[i].value == '_'+id+'_') {
          parent = inputs[i];
          break;
        }
      }
    }
//    if (parent == undefined) return;  // not found;
    if (parent.nodeName.toLowerCase() == "input") {

      // to avoid dublicate runs
      if(SW.App.PlanRate.parents[parent.id]) return;
      SW.App.PlanRate.parents[parent.id] = true;
      
      var tbodies = SW.DOM.getElementsByTagName("tbody", wrapElem);
      var tbodies_matched = new Array();
      for (var i=0; i < tbodies.length; i++) {
        var re = new RegExp('^planRateChild'+id+'(_\\d+)?$');
        if (re.exec(tbodies[i].id)) {
          tbodies_matched.push(tbodies[i]);
        }
      }
      if (tbodies_matched.length) {
        if (parent.getAttribute("swWidgetType") && parent.getAttribute("swWidgetType").toLowerCase() == "spin") {
          SW.Signal.connect(parent, 'onchange', null, function (e) {
            SW.App.PlanRate.toggleChildren(tbodies_matched, (parent.value > 0 ? false : true), parent);
          });
          SW.App.PlanRate.toggleChildren(tbodies_matched, (parent.value > 0 ? false : true), parent);
        } else {
          SW.Signal.connect(parent, 'onclick', null, function (e) {
            SW.App.PlanRate.toggleChildren(tbodies_matched, !parent.checked, parent);
          });
          SW.App.PlanRate.toggleChildren(tbodies_matched, !parent.checked, parent);
        }
      }
    }
  },


  toggleChildren : function (tbodies, disableOrEnable, parent) {
    if(parent && parent.getAttribute("type").toLowerCase() == "radio") {
      var children = SW.DOM.getElementsByTagName('input', document.forms.formEdit);
      for (var i=0; i < children.length; i++) {
        if (children[i].getAttribute("type").toLowerCase() == "radio" &&
            children[i].name == parent.name && children[i].value != parent.value) {
          var children_tbodies = SW.DOM.getElementsByTagName("tbody", document.forms.formEdit);
          var current_children_tbody = new Array();
          for (var iii=0; iii < children_tbodies.length; iii++) {
            var children_value = children[i].value;
            children_value = children_value.replace(/_/g, "");
            var re = new RegExp('^planRateChild'+children_value+'(_\\d+)?$');
            if (re.exec(children_tbodies[iii].id)) {
              current_children_tbody.push(children_tbodies[iii]);
            }
          }
          if(current_children_tbody.length) {
            SW.App.PlanRate.toggleChildren(current_children_tbody, !children[i].checked);
          }
        }
      }
    }
    for (var ii=0; ii < tbodies.length; ii++) {
      var tbody = tbodies[ii];

      var children = SW.DOM.getElementsByTagName('input', tbody);
      var radio = {};
      for (var i=0; i < children.length; i++) {
        if (children[i].getAttribute("type").toLowerCase() == "checkbox") {
          if (children[i].getAttribute("included") && children[i].getAttribute("included").toLowerCase() != "included") {
            children[i].disabled = disableOrEnable;
          }
          if (children[i].getAttribute("included") && children[i].getAttribute("included").toLowerCase() == "included") {
            var hidden_field = document.getElementById('_hidden_' + children[i].name);
            hidden_field.disabled = disableOrEnable;
          }
//          SW.Signal.dispatchEvent(children[i], 'onclick');

          // for nested elements dublicate dispatchEvent by recursion calls
          var m = /^ExtRateAmount\[(\d+)\]\[_(\d+)_\]$/.exec(children[i].name);
          if(m) {
            var parent_id = m[2];
            var children_tbodies = SW.DOM.getElementsByTagName("tbody", document.forms.formEdit);
            var current_children_tbody = new Array();
            for (var iii=0; iii < children_tbodies.length; iii++) {
              var re = new RegExp('^planRateChild'+parent_id+'(_\\d+)?$');
              if (re.exec(children_tbodies[iii].id)) {
                current_children_tbody.push(children_tbodies[iii]);
              }
            }
            if(current_children_tbody.length) {
              SW.App.PlanRate.toggleChildren(current_children_tbody, disableOrEnable ? disableOrEnable : !children[i].checked, children[i]);
            }
          }
        }
        if (children[i].getAttribute("type").toLowerCase() == "radio") {
          children[i].disabled = disableOrEnable;
          if (!radio[children[i].name]) radio[children[i].name] = false;
          if (children[i].checked) radio[children[i].name] = true;
        }
        if (children[i].getAttribute("type").toLowerCase() == "text" &&
            children[i].getAttribute("swWidgetType").toLowerCase() == "spin") {
          //console.log('spin ' + children[i]);
          SW.Widget.Spin.setDisabled(children[i], disableOrEnable);
          SW.App.PlanRate.positiveNumberIndicate.call(children[i]);
      	

        }
      }
  
//      if (!disableOrEnable) {
        for (r in radio) {
          if (radio[r]) continue;
          document.getElementsByName(r)[0].checked = true;
        }
//      }
    }
  },

  toggleNumbers : function (e) {
    var checkbox = this;
    var rel_id = 'ExtRateAmount'+checkbox.id.substring(10);
    var textbox = document.getElementById(rel_id);
    SW.Widget.Spin.setDisabled(textbox, !checkbox.checked);
  },

  positiveNumberIndicate : function (e) {
    var img = SW.DOM.byId('positiveIndicator_'+this.id);
    if (!img) return;
    var myClass = SW.DOM.getClass(img);
    if (this.value > 0 && !this.disabled) {
      if (!myClass.exists('positiveIndicatorOn')) myClass.add('positiveIndicatorOn');
    } else {
      if (myClass.exists('positiveIndicatorOn')) myClass.remove('positiveIndicatorOn');
    }
  }
}




// signal.js


if (typeof(SW.Signal) == 'undefined') {
  SW.Signal = {};
};

// SW.Signal.Event object
SW.Signal.Event = function (src, e) {
  this._event = e || window.event;
  this._src = src;
};

SW.Signal.Event.prototype = {

  src: function () {
    return this._src;
  },

  event: function () {
    return this._event;
  },

  type: function () {
    return this._event.type || undefined;
  },

  target: function () {
    return this._event.target || this._event.srcElement;
  },

  _relatedTarget: null,

  relatedTarget: function () {
    if (this._relatedTarget !== null) {
      return this._relatedTarget;
    }

    var elem = null;
    if (this.type() == 'mouseover') {
      elem = (this._event.relatedTarget ||
        this._event.fromElement);
    } else if (this.type() == 'mouseout') {
      elem = (this._event.relatedTarget ||
        this._event.toElement);
    }
    if (elem !== null) {
      this._relatedTarget = elem;
      return elem;
    }

    return undefined;
  },

  key: function () {
    if (!this.type() || this.type().indexOf('key') !== 0) return undefined;

    var k = {code: 0, string: ''};
    if (typeof(this._event.charCode) != 'undefined' &&
        this._event.charCode !== 0 &&
        !SW.Signal._specialMacKeys[this._event.charCode]) {
      k.code = this._event.charCode;
      k.string = String.fromCharCode(k.code);
    } else if (this._event.keyCode /*&&
               typeof(this._event.charCode) == 'undefined'*/) { // IE
      k.code = this._event.keyCode;
      k.string = String.fromCharCode(k.code);
    }

    return k;
  },

  _mouse: null,

  mouse: function () {
    if (this._mouse !== null) {
        return this._mouse;
    }

    var m = {};
    var e = this._event;

    m.client = new SW.DOM.Coordinates(0, 0);
    if (e.clientX || e.clientY) {
      m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX;
      m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY;
    }

    m.page = new SW.DOM.Coordinates(0, 0);
    if (e.pageX || e.pageY) {
      m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
      m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
    } else {
      /*

          The IE shortcut can be off by two. We fix it. See:
          http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp

          This is similar to the method used in
          MochiKit.Style.getElementPosition().

      */
      var de = document.documentElement;
      var b = document.body;

      m.page.x = e.clientX +
          (de.scrollLeft || b.scrollLeft) -
          (de.clientLeft || 0);

      m.page.y = e.clientY +
          (de.scrollTop || b.scrollTop) -
          (de.clientTop || 0);

    }

    return m;
  },

  stop: function () {
    this.stopPropagation();
    this.preventDefault();
    this._event.__stoped = true;
  },

  stopPropagation: function () {
    if (this._event.stopPropagation) {
        this._event.stopPropagation();
    } else {
        this._event.cancelBubble = true;
    }
  },

  preventDefault: function () {
    if (this._event.preventDefault) {
        this._event.preventDefault();
    } else if (this._confirmUnload === null) {
        this._event.returnValue = false;
    }
  },

  _confirmUnload: null,

  confirmUnload: function (msg) {
    if (this.type() == 'beforeunload') {
      this._confirmUnload = msg;
      this._event.returnValue = msg;
    }
  }
};

/* Safari sets keyCode to these special values onkeypress. */
SW.Signal._specialMacKeys = {
  3: 'KEY_ENTER',
  63289: 'KEY_NUM_PAD_CLEAR',
  63276: 'KEY_PAGE_UP',
  63277: 'KEY_PAGE_DOWN',
  63275: 'KEY_END',
  63273: 'KEY_HOME',
  63234: 'KEY_ARROW_LEFT',
  63232: 'KEY_ARROW_UP',
  63235: 'KEY_ARROW_RIGHT',
  63233: 'KEY_ARROW_DOWN',
  63302: 'KEY_INSERT',
  63272: 'KEY_DELETE'
};

/* for KEY_F1 - KEY_F12 */
for (i = 63236; i <= 63242; i++) {
  SW.Signal._specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1); // no F0
}

/* Standard keyboard key codes. */
SW.Signal._specialKeys = {
  8: 'KEY_BACKSPACE',
  9: 'KEY_TAB',
  12: 'KEY_NUM_PAD_CLEAR', // weird, for Safari and Mac FF only
  13: 'KEY_ENTER',
  16: 'KEY_SHIFT',
  17: 'KEY_CTRL',
  18: 'KEY_ALT',
  19: 'KEY_PAUSE',
  20: 'KEY_CAPS_LOCK',
  27: 'KEY_ESCAPE',
  32: 'KEY_SPACEBAR',
  33: 'KEY_PAGE_UP',
  34: 'KEY_PAGE_DOWN',
  35: 'KEY_END',
  36: 'KEY_HOME',
  37: 'KEY_ARROW_LEFT',
  38: 'KEY_ARROW_UP',
  39: 'KEY_ARROW_RIGHT',
  40: 'KEY_ARROW_DOWN',
  44: 'KEY_PRINT_SCREEN',
  45: 'KEY_INSERT',
  46: 'KEY_DELETE',
  59: 'KEY_SEMICOLON', // weird, for Safari and IE only
  91: 'KEY_WINDOWS_LEFT',
  92: 'KEY_WINDOWS_RIGHT',
  93: 'KEY_SELECT',
  106: 'KEY_NUM_PAD_ASTERISK',
  107: 'KEY_NUM_PAD_PLUS_SIGN',
  109: 'KEY_NUM_PAD_HYPHEN-MINUS',
  110: 'KEY_NUM_PAD_FULL_STOP',
  111: 'KEY_NUM_PAD_SOLIDUS',
  144: 'KEY_NUM_LOCK',
  145: 'KEY_SCROLL_LOCK',
  186: 'KEY_SEMICOLON',
  187: 'KEY_EQUALS_SIGN',
  188: 'KEY_COMMA',
  189: 'KEY_HYPHEN-MINUS',
  190: 'KEY_FULL_STOP',
  191: 'KEY_SOLIDUS',
  192: 'KEY_GRAVE_ACCENT',
  219: 'KEY_LEFT_SQUARE_BRACKET',
  220: 'KEY_REVERSE_SOLIDUS',
  221: 'KEY_RIGHT_SQUARE_BRACKET',
  222: 'KEY_APOSTROPHE'
  // undefined: 'KEY_UNKNOWN'
};

/* for KEY_0 - KEY_9 */
for (var i = 48; i <= 57; i++) {
  SW.Signal._specialKeys[i] = 'KEY_' + (i - 48);
}

/* for KEY_A - KEY_Z */
for (i = 65; i <= 90; i++) {
  SW.Signal._specialKeys[i] = 'KEY_' + String.fromCharCode(i);
}

/* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
for (i = 96; i <= 105; i++) {
  SW.Signal._specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
}

/* for KEY_F1 - KEY_F12 */
for (i = 112; i <= 123; i++) {
  SW.Signal._specialKeys[i] = 'KEY_F' + (i - 112 + 1); // no F0
}


SW.update(SW.Signal, {

  addSubmitEvent : function(obj, handler) {
    //log("addSubmitEvent obj.name="+obj.name+", handler="+handler);
    if (null == obj || typeof(obj) != 'object') return;

    if (null == obj._events) {
      obj._events = [];
      obj._fireFinished = false;
      SW.Signal.connect(obj, 'submit', function (e) {
        SW.Signal._fireEvents.call(obj, e);
      });
    }

    obj._events.push(handler);
  },

  _fireEvents : function(e) {
    //log("SW.Signal._fireEvents");
    this._canContinue = true;
    for (h in this._events) {
      //log("fire "+this._events[h])
      if (!this._events[h]()) {
        this._canContinue = false;
        break;
      }
    }
    this._fireFinished = true;
  },

  __handledContinueObj: false,

  canContinue : function (obj) {
    //log ("SW.Signal.canContinue typeof(obj)="+typeof(obj));
    if (null == obj._events) {
      return true;
    }

    SW.Signal.__handledContinueObj = obj;
    return Signal._waitSubmit();
  },

  _waitSubmit : function(_recursion) {
    obj = Signal.__handledContinueObj;
    if (!obj._fireFinished) {
      obj._timer = setTimeout("Signal._waitSubmit(true);", 100);
    } else {
      obj._fireFinished = false; // to maintain repeat of event list firing
      clearTimeout(obj._timer);
      if (obj._canContinue) {
        if (null == _recursion) return true;  // if timeout didn't happen
        obj.submit(); // timeout happened & false already returned to form
      }
      SW.Signal.__handledContinueObj = false;
    }

    // setTimeout activated
    return false; //obj.canContinue;
  },

  _observers : [],

  _listener : function (src, signal, obj, func) {
    var E = SW.Signal.Event;
    obj = obj || src;

    return function(nativeEvent) {
      var e = new SW.Signal.Event(src, nativeEvent);
      if (nativeEvent.__stoped) return;
      if (signal == "onmouseover" || signal == "onmouseout") {
        try {
          e.relatedTarget().nodeName;
        } catch (err) {
          /* probably hit a permission denied error; possibly one of
            * firefox's screwy anonymous DIVs inside an input element.
            * Allow this event to propogate up.
            */
          return;
        }
        e.stop();
        if (SW.DOM.isChildNode(e.relatedTarget(), src)) {
          // We've moved between our node and a child. Ignore.
          return;
        }
      }

      if (typeof(func) == 'string') {
        return src[func].apply(obj, [e]);
      } else {
        return func.apply(obj, [e]);
      }
    }
  },

  connect : function(src, signal, obj, callback) {
    var self = SW.Signal;
    var isDOM = !!(src.addEventListener || src.attachEvent);
    var listener = self._listener(src, signal, obj, callback);

    if (src.addEventListener) {
      src.addEventListener(signal.substr(2), listener, false);
    } else if (src.attachEvent) {
      src.attachEvent(signal, listener);
    }

    var ident = [src, signal, listener, isDOM, obj, callback];
    self._observers.push(ident);

    return ident;
  },

  _disconnect: function (ident) {
    // check isDOM
    if (!ident[3]) { return; }
    var src = ident[0];
    var sig = ident[1];
    var listener = ident[2];
    if (src.removeEventListener) {
      src.removeEventListener(sig.substr(2), listener, false);
    } else if (src.detachEvent) {
      src.detachEvent(sig, listener); // useCapture unsupported
    } else {
      throw new Error("'src' must be a DOM element");
    }
  },

  disconnect: function (ident) {
    var self = SW.Signal;
    var observers = self._observers;
    if (arguments.length > 1) {
      // compatibility API
      var src = SW.DOM.getElement(arguments[0]);
      var sig = arguments[1];
      var obj = arguments[2];
      var func = arguments[3];
      for (var i = observers.length - 1; i >= 0; i--) {
        var o = observers[i];
        if (o[0] === src && o[1] === sig && o[4] === obj && o[5] === func) {
          self._disconnect(o);
          observers.splice(i, 1);
          return true;
        }
      }
    } else {
      var idx = SW.findIdentical(observers, ident);
      if (idx >= 0) {
        self._disconnect(ident);
        observers.splice(idx, 1);
        return true;
      }
    }
    return false;
  },

  addLoadEvent : function (callback) {
    var root = window.addEventListener || window.attachEvent ?
                 window :
                 document.addEventListener ? document : null;

    if (root) SW.Signal.connect(root, 'onload', null, callback);
    else {
      if(typeof window.onload == 'function') {
        var existing = window.onload;
        window.onload = function () {
          existing();
          callback();
          //SW._waitModulesLoaded(callback);
        }
      } else {
        window.onload = callback;
        //window.onload = SW._waitModulesLoaded(callback);
      }
    }
  },

  addOnBeforeUnloadEvent : function (callback) {
    var root = window.addEventListener || window.attachEvent ?
                 window :
                 document.addEventListener ? document : null;

    if (root) SW.Signal.connect(root, 'onbeforeunload', null, callback);
    else {
      if(typeof window.onbeforeunload == 'function') {
        var existing = window.onbeforeunload;
        window.onbeforeunload = function () {
          existing();
          callback();
          //SW._waitModulesLoaded(callback);
        }
      } else {
        window.onbeforeunload = callback;
        //window.onload = SW._waitModulesLoaded(callback);
      }
    }
  },

  dispatchEvent : function (obj, eventName) {
    if (typeof(obj) == 'string') obj = SW.DOM.byId(obj);
    if (document.createEvent) {
      var ev = document.createEvent('HTMLEvents');
      ev.initEvent(eventName.substr(2), true, true);
      obj.dispatchEvent(ev);
    }  else if (document.createEventObject) {
      obj.fireEvent(eventName);
    }
  }

});



// validate.js


SW.FieldError = function(msg, field) {
  this.msg = msg;
  this.field = field;
}

if (typeof(SW.Validate) == 'undefined') {

  SW.Validate = {

  ProvisionData : function (form, showAlert) {
    //console.log ("SW.Validate.ProvisionData")
    var countError = 0;
    if (form != null && typeof form == "object") {
      for (i = 0; i < form.elements.length; i++) {
        var el = form.elements[i];
        if (el.id != 'validateprov[]') continue;

        var strvalue = el.value;
        strvalue = strvalue.trim();
        if (el.getAttribute("_required") > 0 && strvalue.length <= 0) {
          var errmsg = "";
          if (el.hasAttribute && el.hasAttribute("desc") && el.getAttribute) {
            errmsg = el.getAttribute("desc");
          } else {
            errmsg = locale["JAVASCRIPT_ERROR_ENTER_PROV_DATA"] + " \"" + el.title+"\"!";
          }
          if (showAlert) {
            el.style.backgroundColor='#ffd9d9';
            window.alert(errmsg);
          }
          countError += 1;
        } else {
          el.style.backgroundColor='#FFFFFF';
        }
      }
    }

    return ((countError > 0) ? false : true);
  },


  planRate : function (obj, IncludedValue, maxValue, minValue) {
    if (obj == null || typeof(obj) != "object" || obj.disable) return true;
    //console.log("SW.Validate.planRate ("+IncludedValue+", "+maxValue+")");

    minValue      = parseFloat(minValue);
    maxValue      = parseFloat(maxValue);
    IncludedValue = parseFloat(IncludedValue);

    // remove first zeros to avoid conversion from octal to decimal :)
    while (obj.value.length > 1 && obj.value.substr(0,1) == '0') {
      obj.value = obj.value.substr(1, obj.value.length-1);
    }

    var value = parseInt(obj.value);
    if (isNaN(value)) {
      window.alert(locale["JAVASCRIPT_ERROR_INVALID_DATA"]);
      obj.value = 0;
      obj.focus();
      obj.style.backgroundColor='#ffd9d9';
      return false;
    }

    obj.value = value;
    obj.style.backgroundColor='#FFFFFF';
    if(maxValue == -1) {
      // unlimited resource
      if(obj.value < 0) {
        window.alert(locale["JAVASCRIPT_ERROR_INVALID_DATA"]);
        obj.value = 0;
        obj.focus();
        obj.style.backgroundColor='#ffd9d9';
        return false;
      } else {
        obj.form._canContinue = true;
        return true;
      }
    }
    var max = maxValue - IncludedValue;
    var min = (minValue >= IncludedValue
                    ? minValue - IncludedValue
                    : 0);
    if (obj.value > max) {
      window.alert(locale["JAVASCRIPT_ERROR_AMOUNT_RATE_BIG"] + " " + max+"");
      obj.value = max;
      obj.focus();
      //obj.style.backgroundColor='#ffd9d9';
      return false;
    } else if (obj.value < min) {
      window.alert(locale["JAVASCRIPT_ERROR_AMOUNT_RATE_SMALL"] + " " + min);
      obj.value = min;
      obj.focus();
      //obj.style.backgroundColor='#ffd9d9';
      return false;
    } else {
      //obj.style.backgroundColor='#FFFFFF';
    }

    obj.form._canContinue = true;
    return true;
  },
  
  checkDeps : function (el) {
    var parentIndecies = el.getAttribute("parent");
    if (parentIndecies == null) return true;
    var re = /^(\d+)_(\d+)_(\d+)/;
    var arr = re.exec(parentIndecies);
    var parent = SW.DOM.byId('ExtRateAmount['+arr[1]+'][_'+arr[2]+'_]');
    if (parent == null || typeof(parent) != "object") return true;
    
    var multiplier = 1;
    if (arr[3] > 0) multiplier = arr[3];
    var parent_total = parseInt(parent.getAttribute("validator").substr(9).split("_")[0]) + parseInt(parent.value);
    var child_total = parseInt(el.getAttribute("validator").substr(9).split("_")[0]) + parseInt(el.value);
    //console.log(parent_total + ' < ' + child_total * multiplier);
    if (parent_total < child_total * multiplier) return false;
    else return true;
  },

  allPlanRates : function (form) {
    //console.log("Validator.allPlanRates")

    var inputs = form.getElementsByTagName("input");
    var depBigNums = [];
    for(var i=0; i<inputs.length; i++) {
      var el = inputs[i];
      if (el.type != "text") continue;

      var validator = el.getAttribute("validator");
      if (validator == null || !validator.match(/^planRate/)) continue;

      var re = /^planRate_(\d+\.?\d*)_(\-?\d+\.?\d*)_(\d+\.?\d*)/;
      var arr = re.exec(validator);
      if (!SW.Validate.planRate(el, arr[1], arr[2], arr[3])) return false;
      if (!SW.Validate.checkDeps(el)) {
        depBigNums.push(el.title);
      }
    }
    
    if (depBigNums.length) {
      var bigStr = '  - '+depBigNums.join('\n  - ');
      if (!confirm(locale['DEPS_QUANTITY_EXCEEDED_MESSAGE1']+bigStr+locale['DEPS_QUANTITY_EXCEEDED_MESSAGE2'])) return false;
    }

    return true;
  },

  required : function (field) {
    if (field.getAttribute("_required") && field.value.length == 0) {
      throw new SW.FieldError(locale["ERROR_BLANK_VALUE"], field);
    }
  },

  checkboxRequired : function (field) {
    if (field.getAttribute("_required") && !field.checked) {
      throw new SW.FieldError(locale["PLEASE_CHECK_THIS_FIELD"], field);
    }
  },

  regExp : function (field) {
    if (!field.value.length) return;
    if (field.getAttribute("widgetValidRegExp")) {
      var restr = field.getAttribute("widgetValidRegExp");
      switch (restr) {
        case 'ascii':
          SW.Validate.ascii(field);
          break;

        default:
          var re = new RegExp(eval(restr));
          if (!re.test(field.value)) {
            var msg = field.getAttribute("validateError");
            throw new SW.FieldError(msg, field);
          }
      }
    }
  },

  positiveInt : function (field) {
    if (!field.value.length) return;
    if (!/^\d*$/.test(field.value)) {
      var msg = field.getAttribute("validateError");
      throw new SW.FieldError(msg, field);
    }
  },

  generalInt : function (field) {
    if (!field.value.length) return;
    if (!/^-?\d*$/.test(field.value)) {
      var msg = field.getAttribute("validateError");
      throw new SW.FieldError(msg, field);
    }
  },

  ascii : function (field) {
    if (!field.value.length) return;

    var MULTIBYTE_SPACES = '\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
    
    var charArray = field.value.split("");
    for (var i = 0; i < charArray.length; ++i) {
      // Let's check for multibyte space chars first
      if (MULTIBYTE_SPACES.indexOf(charArray[i]) !== -1) {
        // Gotcha! Replacing with regular space
        charArray[i] = ' ';
        continue;
      }
    
      if (charArray[i].charCodeAt(0) > 127) {
        var msg = field.getAttribute("validateError");
        throw new SW.FieldError(msg, field);
      }
    }
    
    field.value = charArray.join('');
  },

  login : function (field) {
    if (!field.value.length) return;
    var r = new RegExp(SW.settings.loginMask);
    if (!r.test(field.value)) {
      var msg = SW.settings.loginAlert;
      throw new SW.FieldError(msg, field);
    }
  },
  
  password : function (field) {
    if (!field.value.length) return;
  },

  zip : function (field) {
    if (!field.value.length) return;
    value = field.value.trim();
    if (value.length > 10) {
      var msg = field.getAttribute("validateError");
      //var msg = locale["JAVASCRIPT_ERROR_ZIP_CODE"];
      throw new SW.FieldError(msg, field);
    }
  },

  email : function (field) {
    if (!field.value.length) return;
    var emailStr = field.value;
    var emailReg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid
//    var emailRegTwo = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/; // valid (Two instead of 2 -- opera suxx)
    var emailRegTwo = /^[a-zA-Z0-9\+\_\=\!\-]+(\.[a-zA-Z0-9\+\_\=\!\-]+)*\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/; // valid (Two instead of 2 -- opera suxx)
    if (!(!emailReg1.test(emailStr) && emailRegTwo.test(emailStr))) {
      var msg = field.getAttribute("validateError");
      throw new SW.FieldError(msg, field);
    }
  },

  cvv : function (field) {
    if (!field.value.length) return;
    if(!/^(|\d{3,})$/.test(field.value)) {
      var msg = field.getAttribute("validateError")
      throw new SW.FieldError(msg, field);
    }
  },

  issuenumber : function (field) {
    if (!field.value.length) return;
    if(!/^(\d{0,2})$/.test(field.value)) {
      var msg = field.getAttribute("validateError")
      throw new SW.FieldError(msg, field);
    }
  },

  compare : function (field1, field2, message) {
    var field1 = SW.DOM.getElement(field1);
    var field2 = SW.DOM.getElement(field2);
    //console.log ("SW.Validate.compare #"+field1.id+", #"+field2.id)

    if (field1.value != field2.value) {
      var msg = "Fields are not equal";
      if (message.length) msg = message;
      throw new SW.FieldError(msg, field2);
    }
  },

  compareCaseInsensitive : function (field1, field2, message) {
    var field1 = SW.DOM.getElement(field1);
    var field2 = SW.DOM.getElement(field2);
    //console.log ("SW.Validate.compareCaseInsensitive #"+field1.id+", #"+field2.id)

    if (field1.value.toLowerCase() != field2.value.toLowerCase()) {
      var msg = "Fields are not equal";
      if (message.length) msg = message;
      throw new SW.FieldError(msg, field2);
    }
  },

  phoneString : function (field) {
    if (!field.value.length) return;
    re = /^\+?[\d\-\s]+$/;
    if (!re.test(field.value)) {
      var msg = field.getAttribute("validateError")
      throw new SW.FieldError(msg, field);
    }
  },


  // helper for SW.Widget.*.validateAndRender methods
  field : function(field, widgetId) {
    if (field.disabled) return true;
    //console.log("SW.Validate.field name="+field.name+", widget.id="+widgetId);

    var _widget = document.getElementById(widgetId);
    var errorId = "error__"+widgetId.substr(8);
    var error = document.getElementById(errorId);
    var errorClass = SW.DOM.getClass(error);
    var fieldClass = SW.DOM.getClass(_widget);
    try {
      _widget.jsValidator.validate(field);
    }
    catch (e) {
      error.innerHTML = e.msg;
      errorClass.remove("widgetHidden");
      fieldClass.add("widgetErroneous");
      return false;
    }

    error.innerHTML = "";
    errorClass.add("widgetHidden");
    fieldClass.remove("widgetErroneous");

    return true;
  }


  };

};


function EmptyText(value, description) {
  if(value.length > 0) {
    return true;
  }
  window.alert(locale["JAVASCRIPT_ERROR_ENTER_DATA"] + " " + description + "!");
  return false;
}


function ValidatePassword(value, description) {
  var v = value.trim();
  if (v.length <= 0) {
    window.alert(description);
    return false;
  }
  return true;
  /*
  var r = new RegExp(/^[A-Za-z0-9_\+\-\(\)\!\@\#\$\%\^\&\*\"\~\`\.\,\\\|\?\/\;\:]{6,64}$/);
  if(!r.test(value)) {
    window.alert(description);
    return false;
  }
  return true;
  */
}

function ValidateLoginName(value, description) {
  var v = value.trim();
  if (v.length <= 0) {
    window.alert(description);
    return false;
  }
  return true;
  /*
  var r = new RegExp(/^[A-Za-z0-9_\+\-\(\)\!\@\#\$\%\^\&\*\"\~\`\.\,\\\|\?\/\;\:]{6,64}$/);
  if(!r.test(value)) {
    window.alert(description);
    return false;
  }
  return true;
  */
}

function ValidateName(value, description) {
  var r = new RegExp(/.*[0-9\!\@\#\$\%\^\&\*\"\~\`\.\,\\\|\?\/\:\;]+.*/);
  if(!r.test(value)) {
    window.alert(description);
    return false;
  }
  return true;
}

function ValidatePhoneCountryCode(value, description) {
  var r = new RegExp(/^[0-9]{0,11}$/);
  if(!r.test(value)) {
    window.alert(description);
    return true;
  }
  return true;
}

function puncStr(str) {
  str = str.replace("pipe", "|");
  return str.replace(/([\\\|\(\)\[\{\^\$\*\+\?\.])/g,"\\$1");
}


function ValidateZip(value, description) {
  value = value.trim();
  if (value.length > 10) {
    window.alert(description);
    return false;
  }
  zip = getElement("ZipID");
  re = zip.getAttribute("regex");
  if (null != re && re != "") {
    var r = new RegExp(re);
    if(!r.test(value)) {
      window.alert(description);
      return false;
    }
  }
  return true;
}

function ValidateEmail(value, description) {
  var emailStr = value;
  var emailReg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid
//  var emailReg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/; // valid
  var emailRegTwo = /[a-zA-Z0-9]+(\.[a-zA-Z0-9-]*[a-zA-Z0-9]+)*\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/; // valid
  if( emailStr.length <= 0 ) {
    window.alert(description);
    return false;
  } else  if (!(!emailReg1.test(emailStr) && emailRegTwo.test(emailStr))) {
    window.alert(description);
    return false;
  } else {
    return true;
  }
}

function ValidateCVV(value, description) {
  var r = new RegExp(/^(|\d{3,})$/);
  if(!r.test(value)) {
    window.alert(locale["JAVASCRIPT_ERROR_ENTER_DATA"] + " " + description + "!");
    return false;
  }
  return true;
}

function ValidateASCII(value) {
  var r = new RegExp(/^[A-Za-z0-9\s_\-\!\@\#\$\%\^\&\*\"\~\`\.\,\\\|\?\/\:\;]*$/);
  if(!r.test(value)) {
    window.alert(locale["JAVASCRIPT_ERROR_INVALID_ASCII"]);
    return false;
  }
  return true;
}


function ValidateForm(id, validateStrategy) {
  //log ("ValidatForm id="+id)
  var div = document.getElementById(id);
  var result = true;
  if (div == null || typeof div != "object") return false;

  fields = [];
  var inputs = div.getElementsByTagName("input");
  for (var i = 0; i < inputs.length; i++) {
    if (inputs[i].type == "text" || inputs[i].type == "password") {
      fields.push(inputs[i]);
    }
  }
  var selects = div.getElementsByTagName("select");
  for (var i = 0; i < selects.length; i++) {
    fields.push(selects[i]);
  }

  for (var i = 0; i < fields.length; i++) {
    if (fields[i].getAttribute("validator") && !fields[i].disabled) {
      field = fields[i];
      var nameValidator = field.getAttribute("validator").trim();
      var desc = "all necessary data";
      if (field.getAttribute("desc")) {
        desc = field.getAttribute("desc").trim();
      }

      if (validateStrategy == "ascii") {
        result = ValidateASCII(field.value.trim());
        if (!result) {
          field.focus();
          return false;
        }
      }

      switch(nameValidator) {
        case "EmptyText":
          result = EmptyText(field.value.trim(),desc);
          break;
        case "ValidatePassword":
          result = ValidatePassword(field.value.trim(),desc);
          break;
        case "ValidateLoginName":
          result = ValidateLoginName(field.value.trim(),desc);
          break;
        case "ValidateName":
          result = ValidateName(field.value.trim(),desc);
          break;
        case "ValidatePhoneCountryCode":
          result = ValidatePhoneCountryCode(field.value.trim(),desc);
          break;
        case "ValidateZip":
          result = ValidateZip(field.value.trim(),desc);
          break;
        case "ValidateEmail":
          result = ValidateEmail(field.value.trim(),desc);
          break;
        case "cvv":
          result = ValidateCVV(field.value.trim(),desc);
          break;

        default:
          break;
      }

      //log ("validated "+field.name+" with result "+result.toString());

      if (!result) {
        field.focus();
        return false;
      }

    }
  }

  return true;
}


function Compare(id1, id2, MessageError, e) {
  //log ("Compare")
  var e = e || window.event;
  var obj1 =  document.getElementById(id1);
  var obj2 =  document.getElementById(id2);
  if (obj1 != null && obj2 != null) {
    var text1 =  obj1.value.trim();
    var text2  = obj2.value.trim();
    if (text1 != text2) {
      window.alert(MessageError);
      obj2.value = "";
      obj2.focus();
      return false;
    }
  }

  return true
}



// dom.js


SW.DOM = {}

SW.DOM.Coordinates = function (x, y) {
  this.x = x;
  this.y = y;
};

SW.update(SW.DOM, {

  getElement : function(el) {
    return SW.DOM.byId(el);
  },

  byId : function (el) {
    if (typeof(el) == 'object') return el;
    else {
      if (SW.isIE()) {  // IE suxx: getElementById searches by name instead
        var lst = document.getElementsByName(el);
        for (i=0; i<lst.length; i++) {
          if (lst[i].id == el) return lst[i];
        }
      }
      return document.getElementById(el);
    }
  },

  removeChildElements : function(el) {
    while (el.childNodes[0]) {
      el.removeChild(el.childNodes[0]);
    }
  },

  isChildNode: function (node, maybeparent) {
    if (typeof(node) == "string") {
      node = SW.DOM.getElement(node);
    }
    if (typeof(maybeparent) == "string") {
      maybeparent = SW.DOM.getElement(maybeparent);
    }
    if (node === maybeparent) {
      return true;
    }
    while (node && node.tagName.toUpperCase() != "BODY") {
      node = node.parentNode;
      if (node === maybeparent) {
          return true;
      }
    }
    return false;
  },

  getParentByTagName : function(tagName, node) {
    do {
      node = node.parentNode;
    } while (node && 
             node.nodeName.toLowerCase() != tagName.toLowerCase() &&
             node.nodeName.toLowerCase() != 'document');
    return node;
  },

  getElementsByTagName : function(nodeName, wrap, list) {
    //console.log("SW.DOM.getElementsByTagName ("+nodeName+", "+wrap.nodeName+")");
    if (typeof(nodeName) == "string") nodeName = [nodeName];
    if (!wrap) wrap = document;
    if (!list) list = [];
    var child = wrap.firstChild;
    while (child) {
      for (var i=0; i < nodeName.length; i++) {
        if (child.nodeName.toLowerCase() == nodeName[i].toLowerCase()) list.push(child);
      }
      SW.DOM.getElementsByTagName(nodeName, child, list);
      child = child.nextSibling;
    }
    return list;
  },

  _parseQuery : function(query) {
    var result = [];
    var levels = query.split(" ");
    for (var i=0; i < levels.length; i++) {
      if (!levels[i].length) continue;
      var tag = undefined;
      var id = undefined;
      var className = undefined;

      var s = levels[i].split('#');
      if (s[0].length) tag = s[0];
      if (s.length > 1 && s[1].length) {
        id = s[1];
        var c = id.split('.');
        if (c.length > 1) {
          if (c[0].length) id = c[0];
          if (c[1].length) className = c[1];
        }
      } else {
        var c = tag.split('.');
        if (c.length > 1) {
          if (c[0].length) tag = c[0];
          if (c[1].length) className = c[1];
        }
      }

      result.push({'tag' : tag, 'id' : id, 'className' : className});
    }

    return result;
  },

  _findQueryItem : function(qitem, wrap) {
    var me = SW.DOM;
    var child = wrap.firstChild;
    while (child) {
      //if (child.nodeName.toLowerCase() == nodeName[i].toLowerCase()) list.push(child);
      var cmpSuccess = true;
      if (qitem.tag != undefined && qitem.tag != child.nodeName.toLowerCase()) cmpSuccess = false;
      if (qitem.id != undefined && qitem.id != child.id) cmpSuccess = false;
      if (qitem.className != undefined && qitem.className != child.className) cmpSuccess = false;
      if (true == cmpSuccess) {
        return child;
      }
      var node = me._findQueryItem(qitem, child);
      if (node != undefined) return node;
      child = child.nextSibling;
    }

    return undefined;
  },

  queryElement : function(query, wrap) {
    var me = SW.DOM;
    if (!wrap) wrap = document;
    //if (!list) list = [];
    var node = wrap;
    var parsed = me._parseQuery(query);
    for (var i=0; i < parsed.length; i++) {
      node = me._findQueryItem(parsed[i], node);
    }
    if (wrap === node) return undefined;
    else return node;
  },


  toggleWidgets : function (id, bState) {
    if (bState) SW.DOM.enableWidgets(id);
    else SW.DOM.disableWidgets(id);
  },

  adjustDisabledClass : function (el) {
	var cls = SW.DOM.getClass(el);
    if (el.disabled && !cls.exists("disabled")) {
      cls.add("disabled");
    } else if (!el.disabled && cls.exists("disabled")) {
      cls.remove("disabled");
    }
  },
  
  disableWidgets : function (id) {
    //console.log("SW.DOM.disableWidgets " + id);
    //console.trace();
    var div = SW.DOM.getElement(id);
    //if (div.disabled) return;
    div.disabled = true;

    var inputs = div.getElementsByTagName("input");
    for(var i = 0; i < inputs.length; i++) {
      inputs[i]._previousDisabled = inputs[i].disabled;
      inputs[i].disabled = true;
      SW.DOM.adjustDisabledClass(inputs[i]);
    }
    var inputs = div.getElementsByTagName("textarea");
    for(var i = 0; i < inputs.length; i++) {
      inputs[i]._previousDisabled = inputs[i].disabled;
      inputs[i].disabled = true;
      SW.DOM.adjustDisabledClass(inputs[i]);
    }
    var inputs = div.getElementsByTagName("select");
    for(var i = 0; i < inputs.length; i++) {
      inputs[i]._previousDisabled = inputs[i].disabled;
      inputs[i].disabled = true;
      SW.DOM.adjustDisabledClass(inputs[i]);
    }

  },

  enableWidgets : function (id) {
    //console.log("SW.DOM.enableWidgets " + id);
    var div = SW.DOM.getElement(id);
    //if (!div.disabled) return;
    div.disabled = false;

    var inputs = div.getElementsByTagName("input");
    for(var i = 0; i < inputs.length; i++) {
      inputs[i].disabled = false;
      SW.DOM.adjustDisabledClass(inputs[i]);
    }
    var inputs = div.getElementsByTagName("textarea");
    for(var i = 0; i < inputs.length; i++) {
      inputs[i].disabled = false;
      SW.DOM.adjustDisabledClass(inputs[i]);
    }
    var inputs = div.getElementsByTagName("select");
    for(var i = 0; i < inputs.length; i++) {
      inputs[i].disabled = false;
      SW.DOM.adjustDisabledClass(inputs[i]);
    }
  },

  getElementPosition: function (elem, /* optional */relativeTo) {
    //var self = MochiKit.Style;
    var dom = SW.DOM;
    elem = dom.getElement(elem);

//         if (!elem ||
//             (!(elem.x && elem.y) &&
//             (!elem.parentNode == null ||
//             self.computedStyle(elem, 'display') == 'none'))) {
//             return undefined;
//         }

    var c = new SW.DOM.Coordinates(0, 0);
    var box = null;
    var parent = null;

    var d = document;
    var de = d.documentElement;
    var b = d.body;

    if (!elem.parentNode && elem.x && elem.y) {
      /* it's just a MochiKit.Style.Coordinates object */
      c.x += elem.x || 0;
      c.y += elem.y || 0;
    } else if (elem.getBoundingClientRect) { // IE shortcut
      /*

          The IE shortcut can be off by two. We fix it. See:
          http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp

          This is similar to the method used in
          MochiKit.Signal.Event.mouse().

      */
      box = elem.getBoundingClientRect();

      c.x += box.left +
          (de.scrollLeft || b.scrollLeft) -
          (de.clientLeft || 0);

      c.y += box.top +
          (de.scrollTop || b.scrollTop) -
          (de.clientTop || 0);

    } else if (elem.offsetParent) {
      c.x += elem.offsetLeft;
      c.y += elem.offsetTop;
      parent = elem.offsetParent;

      if (parent != elem) {
        while (parent) {
          c.x += parent.offsetLeft;
          c.y += parent.offsetTop;
          parent = parent.offsetParent;
        }
      }

      /*

        Opera < 9 and old Safari (absolute) incorrectly account for
        body offsetTop and offsetLeft.

      */
      var ua = navigator.userAgent.toLowerCase();
      if ((typeof(opera) != 'undefined' &&
        parseFloat(opera.version()) < 9) ||
        (ua.indexOf('safari') != -1 &&
        self.computedStyle(elem, 'position') == 'absolute')) {

        c.x -= b.offsetLeft;
        c.y -= b.offsetTop;

      }
    }

    if (typeof(relativeTo) != 'undefined') {
      relativeTo = arguments.callee(relativeTo);
      if (relativeTo) {
        c.x -= (relativeTo.x || 0);
        c.y -= (relativeTo.y || 0);
      }
    }

    if (elem.parentNode) {
      parent = elem.parentNode;
    } else {
      parent = null;
    }

    while (parent) {
      var tagName = parent.tagName.toUpperCase();
      if (tagName === 'BODY' || tagName === 'HTML') {
        break;
      }
      c.x -= parent.scrollLeft;
      c.y -= parent.scrollTop;
      if (parent.parentNode) {
        parent = parent.parentNode;
      } else {
        parent = null;
      }
    }

    return c;
  },
  
  currentStyle: function (elem) {
    if( window.getComputedStyle ) {
      return window.getComputedStyle(elem, null);  // Firefox
    } else {
      return elem.currentStyle;  // IE
    }
  },

  getElementBox : function (elem) {
    var c = new SW.DOM.Coordinates(0, 0);

    if (elem.offsetWidth) {
      c.x = elem.offsetWidth;
    } else {
      style = SW.DOM.currentStyle(elem);
      //console.log('getElementBox found style: ' + style);
      c.x = style.width.substr(0, elem.currentStyle.width.length-2);
    }
    c.y = elem.offsetHeight;

    return c;
  }


});

if (typeof(SW.DOM.Class) == 'undefined') {
  SW.DOM.getClass = function(object) {
    object = SW.DOM.getElement(object);
    return new SW.DOM.Class(object);
  }

  SW.DOM.Class = function(object) {
    this.object = object;
  }

  SW.DOM.Class.prototype = {

    object : null,

    // returns all element class names as an array of strings
    all : function() {
      return this.object.className.split(/\s+/)
    },

    // whether the class is set to element
    exists : function(className) {
      var classes = this.all()
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] == className) return true
      }
      return false
    },

    // add class to element
    add : function(className) {
      var classes = this.all();
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] == className) return;
      }
      this.object.className = this.object.className + " " + className;
    },

    // remove class from the element classes list
    remove : function(className) {
      var classes = this.all();
      var cn = "";
      for(var i = 0; i < classes.length; i++) {
        if(classes[i] != className) cn = cn + " " + classes[i];
      }
      this.object.className = cn.substr(1);
    },

    // sets/removes class concernging on the value of boolean state
    set : function(className, state) {
      if(state) this.add(className);
      else this.remove(className);
    },

    // adds class to element if it's still not added either removes it
    flip : function(className) {
      if(this.exists(className)) this.remove(className);
      else this.add(className);
    }
  }
}


// async.js


if (typeof(Async) == 'undefined') {
  Async = {

  _winLoadingEventDescriptor : null,

  _onreadystatechange: function (request, callback, winDescr) {
    if (request.readyState != 4) return;
    if (request.status == 200) {
      callback(request.responseText);
      SW.Win.hide('__SW_Async_winLoading');
      SW.Signal.disconnect(winDescr);
    }

  },

  sendXMLHttpRequest: function (uri, callback, e) {
    var request = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
      request = new XMLHttpRequest();
      //request.overrideMimeType("text/xml");
    } else if (window.ActiveXObject) { // IE
      try {
        request = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          request = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {}
      }
    }

    if (!request) {
      console.log("Giving up. Cannot create an XMLHTTP instance");
      return;
    }

    SW.Async._showLoading(e);
    var d = SW.Signal.connect(document, "onmouseover", null, SW.Async._showLoading);

    request.onreadystatechange = function () {
      Async._onreadystatechange(request, callback, d);
    };
    request.open("GET", uri, true);
    request.send(null);
  },

  _showLoading: function (e) {
    if (e == undefined) return;

    var id = '__SW_Async_winLoading';
    var el = SW.Win.create(id);
    //log (el.nodeName)
    el.innerHTML = "Loading...";

    c = e.mouse().page;
    var x = c.x+10; // var x = c.x-60; // for RTL!
    var y = c.y+10;
//console.log('mouse: x='+x+', y='+y);
    SW.Win.show(id, x, y, false);
  }

  };
}

if (typeof(SW.Async) == 'undefined') {
  SW.Async = Async;
}

// window.js



if (typeof(SW.Win) == 'undefined') {
  SW.Win = {

  __hidedObj: false,
  __active : [],

  _push : function (el) {
    for (var i=0; i<SW.Win.windows.length; i++) {
      if (el === SW.Win.windows[i]) return;
    }
    SW.Win.windows.push(el);
  },

  create : function(id) {
    //log("SW.Win.create "+id);
    var el = SW.DOM.getElement(id);

    // create layer of no at all
    if (el == 'undefined' || el == null) {
      //log("create layer");
      el = document.createElement('div');
      el.id=id;
      el.style.visibility = 'hidden';
      document.body.appendChild(el);
      el.style.position = 'absolute';
    }

    // attach events one time
    if (null == el.__Win_created) {
      //log("attach events");
//       Signal.connect(document.body, 'onclick', null, function (e) {
//         SW.Win.hide(el);
//         e.stop();
//       });
//       Signal.connect(el, 'onclick', null, function (e) {
//         console.log('el.onclick trying to stop propagation.');
//         e.stopPropagation();
//       });
      el.__Win_created = true;
    }

    return el;
  },

  createShadow : function(innerElement) {
      var el = document.createElement('table');
      var top = document.createElement('tr');
      var tl = document.createElement('td');
        tl.style.backgroundImage = "url(images/shadow-lt.png)";
        top.appendChild(tl);
      var t = document.createElement('td');
        t.style.backgroundImage = "url(images/shadow-t.png)";
        top.appendChild(t);
      var tr = document.createElement('td');
        tr.style.backgroundImage = "url(images/shadow-rl.png)";
        top.appendChild(tr);
      el.appendChild(top);

      var middle = document.createElement('tr');
      var l = document.createElement('td');
        l.style.backgroundImage = "url(images/shadow-l.png)";
        middle.appendChild(l);
      var r = document.createElement('td');
        r.style.backgroundImage = "url(images/shadow-r.png)";
        middle.appendChild(r);
      el.appendChild(middle);

      var bottom = document.createElement('tr');
      var bl = document.createElement('td');
        bl.style.backgroundImage = "url(images/shadow-lb.png)";
        bottom.appendChild(bl);
      var b = document.createElement('td');
        b.style.backgroundImage = "url(images/shadow-b.png)";
        bottom.appendChild(b);
      var br = document.createElement('td');
        br.style.backgroundImage = "url(images/shadow-rb.png)";
        bottom.appendChild(br);
      el.appendChild(bottom);

      return el;
  },

  _addHideHandler : function () {
    var last = SW.Win.__active[SW.Win.__active.length - 1];
    last.conn = SW.Signal.connect(document.body, "onclick", null, function (e) {
      SW.Win.hide(last.win);
    });
  },

  show : function(id, /*optional*/ x, /*optional*/ y, /*optional*/ hideOnClick) {
    //console.log("SW.Win.show "+id+", x = "+x+", y = "+y);
    var el = SW.Win.create(id);
    el.style.visibility = 'visible';
    if (null != x) el.style.left = x+'px';
    if (null != y) el.style.top = y+'px';
    if (hideOnClick == undefined) hideOnClick = true;

    SW.Win.__active.push({win : el, conn : null});
    if (hideOnClick) setTimeout("SW.Win._addHideHandler();", 100);

    return el;
  },

  hide : function(id) {
    //console.log("SW.Win.hide "+id)
    var el = SW.DOM.getElement(id);
    if (el == 'undefined' || el == null
        || el.style.visibility == "hidden") return;

    if (SW.Win.__active.length) {
      var last = SW.Win.__active.shift();
      SW.Signal.disconnect(last.conn);
    }

    // hide if ok
    //if (el.onblur) el.onblur();
    el.style.visibility = "hidden";
    return false;
  },

  hideAllExcept : function(el) {
    //console.log("##########  hideAllExcept  ##############################");
    //logDump(el);
    for (var i=0; i < SW.Win.windows.length; i++) {
    //log(SW.Win.windows[i].nodeName+" != "+el.nodeName);
      if (SW.Win.windows[i] != el) SW.Win.hide(SW.Win.windows[i]);
    }
  },

  isHidden : function(id) {
    var el = SW.DOM.getElement(id);
    if (el == 'undefined' || el == null
        || el.style.visibility == "hidden") return true;

    return false;
  },


  showInfo: function (id, c, text) {
    var el = SW.Win.create(id);
    //log (el.nodeName)
    el.innerHTML = text;
    //el = SW.Win.createShadow(el);

    //c = SW.DOM.getElementPosition(obj);
    //var x = SW.Win.findPosX(obj)+3; y = SW.Win.findPosY(obj)+3;
//console.log('x='+c.x+', y='+c.y);
    var x = c.x+10; y = c.y+10;
    var docElem = document.documentElement;
    var pageW = docElem.clientWidth, pageH = docElem.clientHeight;
    var scrollY = docElem.scrollTop, scrollX = docElem.scrollLeft;
    var w = el.offsetWidth, h = el.offsetHeight;

    //console.log("top: "+y+", height: "+h+", scrollY: "+scrollY+", pageH: "+pageH);

// as pageH was 105 instead of ~500 in FirstServ
// TODO: ivestigate problem
//     if ((y + h) > (pageH + scrollY)) {
//       y =  y - ((y + h) - (pageH + scrollY));
//     }
//     if (y < scrollY) y = scrollY;


    //el.innerHTML = text;
    SW.Win.show(id, x, y)
  },

  findPosX: function (obj) {
    var currleft = 0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        currleft += obj.offsetLeft
        obj = obj.offsetParent;
      }
    }
    else if (obj.x) currleft += obj.x;

    return currleft;
  },

  findPosY: function (obj) {
    var currtop = 0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        currtop += obj.offsetTop
        obj = obj.offsetParent;
      }
    }
    else if (obj.y) currtop += obj.y;

    return currtop;
  },


  //category.tpl, neworder.tpl
  toggle2 : function (el1, el2, /*optional*/ displayStyle) {
    var obj1 = SW.DOM.getElement(el1);
    var obj2 = SW.DOM.getElement(el2);

    if (null == displayStyle) displayStyle = "block";

    if (obj1.style.display == "none") {
      obj1.style.display = displayStyle;
      obj2.style.display = "none";
    } else {
      obj1.style.display = "none";
      obj2.style.display = displayStyle;
    }

    return false;
  },

  //category.tpl
  toggle2Text : function (id, firstText, secondText) {
    obj = document.getElementById(id);
    firstText = firstText.trim();
    secondText = secondText.trim();
    if (obj != null && typeof obj == "object") {
      if (null == obj.innerHTML || obj.innerHTML.trim() == firstText) {
        obj.innerHTML = secondText;
      } else {
        obj.innerHTML = firstText;
      }
    }
  }


  };
}

// combo.js


if (typeof(SW.Combo) == 'undefined') {
  SW.Combo = {

  __items : [],
  activeBox : null,

  convert : function (fromElement) {
    //console.log("SW.Combo.convert "+fromElement);
    fromElement = SW.DOM.getElement(fromElement);
    if (null == fromElement || fromElement.nodeName.toLowerCase() != 'select') {
      return;
      //throw 'Invalid element';
    }

    var span = document.createElement('span');
    span.id = 'combo__'+fromElement.id;
    span.className = 'SWCombo';
    span.__from = fromElement;
    elementWidth = SW.DOM.getElementBox(fromElement).x;

    // TODO: add option to disable widget
//     if (fromElement.getAttribute('disabled')) {
//       span.setAttribute('disabled', 'true');
//       span.className = 'SWCombo disabled';
//     }

    var ul = document.createElement('ul');
    ul.className = 'SWCombo';
    ul.style.position = 'absolute';
    ul.style.display = 'block';

    SW.Combo.populate(fromElement, span, ul);

    SW.Win.hide(ul);
    span.__ul = ul;
    ul.__span = span;

    //ul.style.width = span.offsetWidth;
    fromElement.style.display = 'none';
    fromElement.parentNode.appendChild(span);
    fromElement.parentNode.appendChild(ul);

    fromElement.__span = span;
    fromElement.__ul = ul;

    if (elementWidth < 65) elementWidth = 65;
    span.style.width = (elementWidth-2)+'px';


    var x = SW.Win.findPosX(span);
    var y = SW.Win.findPosY(span) + span.offsetHeight;
    c = SW.DOM.getElementPosition(span);
    //console.log("x = " + c.x + ", y = " + c.y + ", width = " + span.offsetWidth)
    ul.style.left = x;
    ul.style.top = y;
    ul.style.position = 'absolute';
    //var w = 150;
    //if (span.offsetWidth) w = span.offsetWidth - 2;
    //ul.style.width = w + "px";

    if (span.__ul.offsetHeight > 200) {
      span.__ul.style.height = '200px';
      span.__ul.style.overflow = 'scroll';
    }

    //span.onclick = SW.Combo.spanClick;
    SW.Signal.connect(span, 'onclick', null, SW.Combo.spanClick);
    //span.onkeypress = SW.Combo.spanKeypress;
    SW.Signal.connect(document, 'onclick', null, SW.Combo.documentBlur);

    var keySignal = 'onkeypress';
    if (SW.Browser.ie) keySignal = 'onkeyup';
    SW.Signal.connect(document, keySignal, span, SW.Combo.spanKeypress);

    span.onmouseover = SW.Combo.spanOver;
    span.onmouseout = SW.Combo.spanOut;
    SW.Signal.connect(span, 'onblur', null, SW.Combo.spanBlur);
    //span.onblur = SW.Combo.spanBlur;

    SW.Combo.__items[SW.Combo.__items.length] = span;
  },

  populate : function(fromElement, span, ul) {
    //console.log('SW.Combo.populate');
    SW.DOM.removeChildElements(ul);

    var i=0;
    for (; i<fromElement.options.length; i++) {
      var opt = fromElement.options[i];
      var li = document.createElement('li');
      if (opt.selected) {
        li.className = 'selected';
        span.innerHTML = '<table cellpadding="0" cellspacing="1"><tr><td class="label"><label>'+opt.innerHTML+'</label></td><td class="combo-button"></td></tr></td>';
      }
      if (opt.disabled) {
        li.setAttribute("disabled", "true");
        li.className = 'disabled';
      }
      li.innerHTML = opt.text.trim();
      li.__index = i;
      li.__value = opt.value;
      li.__span = span;


      SW.Signal.connect(li, 'onclick', null, SW.Combo.itemClick);
      li.onmouseover = SW.Combo.itemOver;
      ul.appendChild(li);
    }

  },

  spanClick : function (e) {
    //log("SW.Combo.spanClick");
    var x = SW.Win.findPosX(this);
    var y = SW.Win.findPosY(this) + this.offsetHeight;
    var w = (this.offsetWidth - 2);
    //log(w+" > "+(this.__ul.offsetWidth-2));
    if (w > this.__ul.offsetWidth-2) this.__ul.style.width = w + 'px';

    var lis = this.__ul.childNodes;
    for (var i=0; i<lis.length; i++) {
      //lis[i].style.width = '100%';//(this.__ul.offsetWidth - 4) + 'px';
    }

    var lis = this.__ul.childNodes;
    for (var i=0; i<lis.length; i++) {
      if (lis[i].getAttribute("disabled")) continue;
      if (i != this.__from.selectedIndex) lis[i].className = '';
      else lis[i].className = 'selected';
    }

    this.__ul.style.height = 'auto';
    this.__ul.style.overflow = 'auto';
    if (this.__ul.offsetHeight > 200) {
      this.__ul.style.height = '200px';
      this.__ul.style.overflow = 'scroll';
      this.__ul.scrollTop = lis[this.__from.selectedIndex].offsetTop;
    }

    if (SW.Win.isHidden(this.__ul)) {
      c = SW.DOM.getElementPosition(this);
      SW.Win.show(this.__ul, x, y);
    } else {
      SW.Win.hide(this.__ul);
      this.childNodes[0].className = "selected";
      this.focus();
    }

  },

  spanKeypress : function (e) {
    //log("SW.Combo.spanKeypress")
    //if (e.keyCode != 38 && e.keyCode != 40) return;
    if (SW.Win.isHidden(this.__ul) &&
        this.childNodes[0].className != "selected") return;

    // find selected item
    var lis = this.__ul.childNodes;
    var pos = SW.Combo.findCursor(this.__ul);

    // down arrow
    if (e._event.keyCode == 40) {
      if (pos != lis.length-1) {
        if (lis[pos+1].getAttribute("disabled") && pos+2 < lis.length) pos++;
        SW.Combo._itemSelect.call(lis[pos+1], e);
        //SW.Combo.moveCursor(lis[pos+1]);
      }
      e.stop();
    }

    // up arrow
    if (e._event.keyCode == 38) {
      if (lis[pos-1].getAttribute("disabled") && pos-2 >= 0) pos--;
      if (pos != 0) SW.Combo._itemSelect.call(lis[pos-1], e);
      //SW.Combo.moveCursor(lis[pos-1]);
      e.stop();
    }

    // cancel or enter
    if (e._event.keyCode == 13 || e._event.keyCode == 27) {
      SW.Combo._itemSelect.call(lis[pos], e);
      SW.Win.hide(this.__ul);
      e.stop();
    }

    // charachter key pressed
    var mychar = e.key().string.toLowerCase();
    if (mychar.length) {
      if (pos < lis.length-1 &&
          lis.length && lis[pos+1].innerHTML.substr(0, 1).toLowerCase() == mychar) {
        SW.Combo._itemSelect.call(lis[pos+1], e);
        //SW.Combo.moveCursor(lis[pos+1]);
      } else {
        var found = false;
        if (pos < lis.length) {
          for (var i=pos+1; i<lis.length; i++) {
            if (lis[i].innerHTML.substr(0, 1).toLowerCase() == mychar) {
              SW.Combo._itemSelect.call(lis[i], e);
              //SW.Combo.moveCursor(lis[i]);
              found = true;
              break;
            }
          }
        }
        if (!found) {
          for (var i=0; i<lis.length; i++) {
            if (lis[i].innerHTML.substr(0, 1).toLowerCase() == mychar) {
              SW.Combo._itemSelect.call(lis[i], e);
              //SW.Combo.moveCursor(lis[i]);
              break;
            }
          }
        }
      }
      e.stop();
    }

    var scroll = this.__ul.scrollTop;
    pos = SW.Combo.findCursor(this.__ul);
    var offset = this.__ul.childNodes[pos].offsetTop;
    var height = this.__ul.offsetHeight-35;
    if (scroll > offset) {
      this.__ul.scrollTop = offset;
    } else if (scroll < offset-height) {
      this.__ul.scrollTop = offset-height;
    }
  },

  findCursor : function (ul) {
    var lis = ul.childNodes;
    var pos = 0;
    for (var i=0; i<lis.length; i++) {
      if (lis[i].className == 'selected') {
        pos = i;
        break;
      }
    }
    return pos;
  },

  moveCursor : function (liItem) {
    if (liItem.getAttribute("disabled")) return;

    liItem.__span.innerHTML = '<table cellpadding="0" cellspacing="1"><tr><td class="label"><label>'+liItem.innerHTML+'</label></td><td class="combo-button"></td></tr></td>';

    var lis = liItem.parentNode.childNodes;
    for (var i=0; i<lis.length; i++) {
      if (lis[i].getAttribute("disabled")) continue;
      lis[i].className = '';
    }
    liItem.className = 'selected';
  },

  _itemSelect : function (e) {
    //log("SW.Combo.itemSelect "+this.__index+": "+this.innerHTML);
    if (this.getAttribute("disabled")) return;

    SW.Combo.moveCursor(this);

    var select = this.__span.__from;
    if (select.selectedIndex != this.__index) {
      select.selectedIndex = this.__index;
      if (select.onchange) select.onchange();
    }
  },

  itemClick : function (e) {
    //log("SW.Combo.itemClicked "+this.innerHTML);
    if (this.getAttribute("disabled")) {
      e.stop();
      return;
    }
    SW.Combo._itemSelect.call(this, e);
    SW.Win.hide(this.parentNode);
  },

  itemOver : function (e) {
    var lis = this.parentNode.childNodes;
    for (var i=0; i<lis.length; i++) {
      if (lis[i].getAttribute("disabled")) continue;
      lis[i].className = '';
    }
    if (this.getAttribute("disabled")) return;
    this.className = 'selected';
  },

  spanOver : function (e) {
    this.className = 'SWCombo SWCombo_hl';
  },

  spanOut : function (e) {
    this.className = 'SWCombo';
  },

  spanBlur : function (e) {
    //console.log("SW.Combo.spanBlur");
    this.className = 'SWCombo';
    this.childNodes[0].className = '';
  },

  documentBlur : function (e) {
    //console.log("SW.Combo.documentBlur");
    for (var i=0; i<SW.Combo.__items.length; i++) {
      if (SW.Combo.__items[i] !== e._event.doNotBlur) {
        SW.Combo.spanBlur.call(SW.Combo.__items[i], e);
      }
    }
  }

  };

}




// widget.js



if (typeof(SW.Widget) == 'undefined') SW.Widget = {};
  SW.update(SW.Widget, {

  _widgets : {},

  _convert : function (tag, widget, mark) {
    //console.log('  _convert '+tag+', '+widget);

    var elems = document.getElementsByTagName(tag);
    for (var i = 0; i < elems.length; i++) {
      var widgetType = elems[i].getAttribute("swWidgetType");
      if (null != widgetType && widgetType == "custom") continue;
      widget.convert(elems[i]);
    }
  },

  _waitConvert : function (tag, widgetString) {
    loader(function () {
      SW.Widget._convert(tag, eval(widgetString));
    }, [widgetString]);
  },

  convert : function() {
//     console.log('SW.Widget.convert');
//     SW.Widget._waitConvert('button', 'SW.Button');
//     SW.Widget._waitConvert('textarea', 'SW.Widget.Textarea');
//     SW.Widget._waitConvert('input', 'SW.Widget.Spin');
    SW.Widget._convert('button', SW.Button);
    SW.Widget._convert('textarea', SW.Widget.Textarea);
    SW.Widget._convert('input', SW.Widget.Spin);
    SW.Widget._convert('a', SW.Widget.AjaxQuestion);
    SW.Widget._convert('a', SW.Widget.PostLink);
    //SW.Widget._convert('select', SW.Combo);
  },

  startEventEngine : function (form) {
    ws = form.getElementsByTagName("div");
    for (var i = 0; i < ws.length; i++) {
      if (ws[i].id.substr(0,8) == "widget__") {
        SW.Widget.setValidationEvents(ws[i]);
      }
    }
    SW.Signal.connect(form, "onsubmit", null, SW.Widget._onSubmitForm)
  },

  _onSubmitForm : function (e) {
    var passed = true;
    //var form = e._src;
    var ws = e._src.getElementsByTagName("div");
    for (var i = 0; i < ws.length; i++) {
      var widget = ws[i];
      if (widget.id.substr(0,8) != "widget__") continue;
      //var type = SW.Widget.getType(widget);
      //if (!SW.Widget[type].validateAndRender(widget)) {
      if (!widget.jsValidator.validateAndRender(widget)) {
        //console.log("validation failed. widget id="+widget.id);
        passed = false;
      }
    }

    if (!passed) {
      alert(locale["ERROR_FIELDS_GENERAL"]);
      //throw Error(locale["ERROR_FIELDS_GENERAL"]);
      e.stop();
      //e._event.__stoped = true;
      var btn = SW.DOM.getElement('apt');
      if(btn) {
        SW.Button.setDisabled(btn, false);
      }
    } else {
      var btn = SW.DOM.getElement('apt');
      if(btn) {
        SW.Button.setDisabled(btn, true);
      }
    }
  },

  getType : function (widget) {
    if (typeof(widget) == 'string') {
      widget = SW.DOM.getElement(widget);
    }
    if (widget.id.substr(0, 8) != 'widget__') {
      throw Error("Widget wrapper block ID must be like 'widget__*NAME*'");
    }

    var type = "text";
    if (!widget.getAttribute('type')) {
      //throw Error("Widget wrapper must have 'type' attribute.");
    } else {
      type = widget.getAttribute('type');
    }

    return type;
  },

  setValidationEvents : function (widget) {
    if (typeof(widget) == 'string') {
      widget = SW.DOM.getElement(widget);
    }

    var type = SW.Widget.getType(widget);
    widget.jsValidator = new SW.Widget[type](widget);

    // fuck! :( had to remove this great piece of shit below
    // never mind, once I'll make it really comprehensive
    // widget.jsValidator.setValidationEvents(widget);
  }

  });


SW.Widget.text = function (widget) {
  this.widget = widget;
  this.customValidators = [];
}

SW.Widget.text.prototype = {
  toString : function () {
    return 'SW.Widget.text';
  },

  setValidationEvents : function(widget) {
    //console.log("SW.Widget.text.setValidationEvents "+widget.id);
    var input = widget.getElementsByTagName("input")[0];
    var self = this;

    SW.Signal.connect(input, 'onblur', null, function (e) {
      self.validateAndRender(widget);
    });
    SW.Signal.connect(input, 'onkeyup', null, function (e) {
      if (e._event.keyCode === 9) return;
      self.validateAndRender(widget);
    });
  },

  validateAndRender : function (widget) {
    var input = widget.getElementsByTagName("input")[0];
    return SW.Validate.field(input, widget.id);
  },

  addValidator : function (validator) {
    this.customValidators.push(validator);
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.regExp(field);
    for (var i = 0; i < this.customValidators.length; i++) {
      this.customValidators[i](field);
    }
  }
}

SW.Widget.checkbox = function (widget) {
console.log('SW.Widget.checkbox');
  SW.Widget.text.call(this, widget);
}


//SW.Widget.checkbox.prototype = SW.Widget.text.prototype;
SW.update(SW.Widget.checkbox.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.checkbox';
  },

  validate : function (field) {
    checked_field = SW.DOM.byId(field.name);
    SW.Validate.checkboxRequired(checked_field);
  }
});

SW.Widget.textarea = function (widget) {
  SW.Widget.text.call(this, widget);
}

//SW.Widget.textarea.prototype = SW.Widget.text.prototype;
SW.update(SW.Widget.textarea.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.textarea';
  },

  setValidationEvents : function(widget) {
    //console.log("SW.Widget.text.setValidationEvents "+widget.id);
    var input = widget.getElementsByTagName("textarea")[0];
    var self = this;

    SW.Signal.connect(input, 'onblur', null, function (e) {
      self.validateAndRender(widget);
    });
    SW.Signal.connect(input, 'onkeyup', null, function (e) {
      if (e._event.keyCode === 9) return;
      self.validateAndRender(widget);
    });
  },

  validateAndRender : function (widget) {
    var input = widget.getElementsByTagName("textarea")[0];
    return SW.Validate.field(input, widget.id);
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.regExp(field);
  }
});

SW.Widget.login = function (widget) {
  SW.Widget.text.call(this, widget);
}

//SW.Widget.login.prototype = SW.Widget.text.prototype;
SW.update(SW.Widget.login.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.login';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.login(field);
    SW.Validate.regExp(field);
  }
});

SW.Widget.password = function (widget) {
  SW.Widget.text.call(this, widget);
}

//SW.Widget.login.prototype = SW.Widget.text.prototype;
SW.update(SW.Widget.password.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.password';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.password(field);
    SW.Validate.regExp(field);
    for (var i = 0; i < this.customValidators.length; i++) {
      this.customValidators[i](field);
    }
  }
});


SW.Widget.zip = function (widget) {
  SW.Widget.text.call(this, widget);
}

//SW.Widget.zip.prototype = SW.Widget.text.prototype;
SW.update(SW.Widget.zip.prototype, SW.Widget.text.prototype, {
  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.zip(field);
    SW.Validate.regExp(field);
  }
});

SW.Widget.email = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.email.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.email';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.email(field);
    SW.Validate.regExp(field);
    for (var i = 0; i < this.customValidators.length; i++) {
      this.customValidators[i](field);
    }
  }
});

SW.Widget.cvv = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.cvv.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.cvv';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.cvv(field);
    SW.Validate.regExp(field);
  }
});

SW.Widget.issuenumber = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.issuenumber.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.issuenumber';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.issuenumber(field);
    SW.Validate.regExp(field);
  }
});

SW.Widget.generalInt = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.generalInt.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.generalInt';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.generalInt(field);
    SW.Validate.regExp(field);
  }
});

SW.Widget.longInt = function (widget) {
	SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.longInt.prototype, SW.Widget.text.prototype, {
	toString : function () {
	return 'SW.Widget.longInt';
},

validate : function (field) {
	SW.Validate.required(field);
	SW.Validate.positiveInt(field);
	SW.Validate.regExp(field);
}
});


SW.Widget.radio = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.radio.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.radio';
  },

  validate : function (field) {
    SW.Validate.required(field);
  }
});

SW.Widget.phone = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.phone.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.phone';
  },

  setValidationEvents : function(widget) {
    //console.log("SW.Widget.phone.setValidationEvents "+widget.id);

    var self = this;
    var fields = widget.getElementsByTagName("input");
    for (var i = 0; i < fields.length; i++) {
      SW.Signal.connect(fields[i], 'onblur', null, function (e) {
        self.validateAndRender(widget);
      });
      SW.Signal.connect(fields[i], 'onkeyup', null, function (e) {
        if (e._event.keyCode === 9) return;
        self.validateAndRender(widget);
      });
    }
  },

  validateAndRender : function (widget) {
    var fields = widget.getElementsByTagName("input");

    //var passed = true;
    for (var i = 0; i < fields.length; i++) {
      if (!SW.Validate.field(fields[i], widget.id)) {
        return false;
      }
    }

    return true;
  },

  validate : function (field) {
    SW.Validate.required(field);
    if (field.id.substr(0, 7) != 'number_') SW.Validate.positiveInt(field);
    else SW.Validate.phoneString(field);
    SW.Validate.regExp(field);
    if (field.id.substr(0, 5) == 'area_') {
      var c_id = 'country_' + field.id.substr(5);
      var num = SW.DOM.byId('country_' + field.id.substr(5));
      if (/^0+$/.test(field.value) ||
          num != undefined && num.value == 1 && /^1+$/.test(field.value)) {
        var msg = field.getAttribute("validateError")
        throw new SW.FieldError(msg, field);
      }
    }
  }
});

SW.Widget.combo = function (widget) {
  SW.Widget.text.call(this, widget);
}

SW.update(SW.Widget.combo.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.combo';
  },

  setValidationEvents : function(widget) {
    var select = widget.getElementsByTagName("select")[0];
    var self = this;

    SW.Signal.connect(select, 'onchange', null, function (e) {
      self.validateAndRender(widget);
    });
  },

  validateAndRender : function (widget) {
    var select = widget.getElementsByTagName("select")[0];
    return SW.Validate.field(select, widget.id);
  },

  validate : function (field) {
    SW.Validate.required(field);
    for (var i = 0; i < this.customValidators.length; i++) {
      this.customValidators[i](field);
    }
  }
});

if (typeof(SW.Button) == 'undefined') {
  SW.Button = {

  convert : function (button) {
    //console.log("SW.Button.convert "+button.id);
    SW.Signal.connect(button, 'onmouseover', null, SW.Button._onMouseOver);
    SW.Signal.connect(button, 'onmouseout', null, SW.Button._onMouseOut);
    var buttonClass = SW.DOM.getClass(button);
    if (!buttonClass.exists("SWbutton")) {
      buttonClass.add("SWbutton");
    }
    if (button.disabled) {
      buttonClass.add("SWbutton_Disable");
    }
  },

  setDisabled : function (button, isDisabled) {
    //console.log('SW.Button.setDisabled '+button+', '+isDisabled);
    var buttonClass = SW.DOM.getClass(button);
    if (isDisabled) {
      if (!button.disabled) {
        button.disabled = true;
        buttonClass.add("SWbutton_Disable");
      }
    } else {
      if (button.disabled) {
        button.disabled = false;
        buttonClass.remove("SWbutton_Disable");
      }
    }
  },

  _onMouseOver : function (e) {
    //console.log("SW.Button._onMouseOver")
    if (e.src().disabled) return;
    var buttonClass = SW.DOM.getClass(e.src());
    buttonClass.remove("SWbutton");
    buttonClass.add("SWbutton_Over");
  },

  _onMouseOut : function (e) {
    //console.log("SW.Button._onMouseOut")
    if (e.src().disabled) return;
    var buttonClass = SW.DOM.getClass(e.src());
    buttonClass.remove("SWbutton_Over");
    buttonClass.add("SWbutton");
  }

  }
}


if (typeof(SW.Widget.Textarea) == 'undefined') {
  SW.Widget.Textarea = {

  _widgets : {},

  convert : function (textarea) {
    //console.log('SW.Widget.Textarea.convert');

    var me = SW.Widget.Textarea;
    if (me._widgets[textarea.id]) return;
    me._widgets[textarea.id] = true;

    var wrap = document.createElement('div');
    var grippie = document.createElement('div');

    var textNew = textarea.cloneNode(true);
    textNew.__grippie = grippie;
    wrap.appendChild(textNew);
    wrap.appendChild(grippie);
    textarea.parentNode.insertBefore(wrap, textarea);
    textarea.parentNode.removeChild(textarea);

    grippie.style.width = (SW.DOM.getElementBox(textNew).x - 2) + 'px';
    wrap.className = "resizable-textarea";
    grippie.className = "grippie";

    SW.Signal.connect(document, 'onmousedown', textNew, SW.Widget.Textarea.startDrag);
    //SW.Signal.connect(grippie, 'onmousedown', textNew, SW.Widget.Textarea.startDragDoc);
  },

  startDrag : function (e) {
    //console.log("startDrag ");
  },

  startDrag : function (e) {
    if (e.target() != this.__grippie) return;
    this.__offset = e._event.screenY; //e.mouse().client.y;
    this.__height = this.offsetHeight;
    this.style.opacity = '0.25';
    this.__mousemove = SW.Signal.connect(document, 'onmousemove',
                                         this, SW.Widget.Textarea.performDrag);
    this.__mouseup = SW.Signal.connect(document, 'onmouseup',
                                       this, SW.Widget.Textarea.endDrag);
  },

  performDrag : function (e) {
    SW.Widget.Textarea._height(this, e);
    this.__offset = e._event.screenY;
  },

  endDrag : function (e) {
    SW.Widget.Textarea._height(this, e);
    this.style.opacity = '1';
    SW.Signal.disconnect(this.__mousemove);
    //this.__mousemove = undefined;
    SW.Signal.disconnect(this.__mouseup);
    //this.__mouseup = undefined;
  },

  _height : function (elem, e) {
    var y = e._event.screenY;//e.mouse().page.y; //e._event.clientY;
    var h = elem.__height + (y - elem.__offset);
    //console.log(h+' = '+elem.__height+' + ('+y+' - '+elem.__offset+')');
    if (h > 0) {
      elem.__offset = y;
      elem.__height = h;
      elem.style.height = h+'px';
      //console.log('new offset: '+elem.__offset);
    }
  }

  }
}


if (typeof(SW.Widget.AjaxQuestion) == 'undefined') {
  SW.Widget.AjaxQuestion = {

  _widgets : {},

  convert : function (a) {
    //console.log('SW.Widget.Textarea.convert');
    var wtype = a.getAttribute('swWidgetType');
    if (wtype != 'AjaxQuestion' && a.className != 'question_icon') return;

    var me = SW.Widget.AjaxQuestion;
    //if (me._widgets[a.href]) return;
    //me._widgets[a.href] = true;

    a.onclick = function (e) {return false;};
    SW.Signal.connect(a, 'onclick', null, me.click);
  },

  click : function (e) {
    var c = e.mouse().page;//SW.DOM.getElementPosition(this);
    var id = 'wininfo'
    Async.sendXMLHttpRequest(this.href, function (text) {
      //SW.Win.showInfo("wininfo", this, text);
      var el = SW.Win.create(id);
      el.innerHTML = text;
      SW.Win.show(id, c.x+10, c.y+10); // SW.Win.show(id, c.x-250, c.y+10);  // for RTL! 
    }, e);
    //e.preventDefault();
  }

  }
}


if (typeof(SW.Widget.PostLink) == 'undefined') {
  SW.Widget.PostLink = {

  _widgets : {},

  convert : function (a) {
    //console.log('SW.Widget.Textarea.convert');
    var wtype = a.getAttribute('swWidgetType');
    if (wtype != 'PostLink') return;

    var me = SW.Widget.PostLink;
    //if (me._widgets[a.href]) return;
    //me._widgets[a.href] = true;

    a.onclick = function (e) {return false;};
    SW.Signal.connect(a, 'onclick', null, me.click);
  },

  click : function (e) {
    console.log('a.clicked. href='+this.href);
    var strParams = this.href.substring(this.href.indexOf('?')+1);
    var params = args = [];
    while (strParams.length) {
      var nextTokenPos = strParams.indexOf('&');
      if (nextTokenPos == -1) {
        strPair = strParams;
        strParams = '';
      } else {
        var strPair = strParams.substring(0, nextTokenPos);
        strParams = strParams.substring(nextTokenPos+1);
      }
      pair = strPair.split('=', 2);
      params[pair[0]] = pair[1];
      args.push(pair[0], pair[1]);
      console.log(pair[0]+' = '+pair[1]);
    }

    post(args);
  }

  }
}

SW.Widget.ascii = function (widget) {
  SW.Widget.text.call(this, widget);
}

//SW.Widget.login.prototype = SW.Widget.text.prototype;
SW.update(SW.Widget.ascii.prototype, SW.Widget.text.prototype, {
  toString : function () {
    return 'SW.Widget.ascii';
  },

  validate : function (field) {
    SW.Validate.required(field);
    SW.Validate.ascii(field);
    SW.Validate.regExp(field);
  }
});




// spin.js


//include('../js/widget.js');

if (typeof(SW.Widget) == 'undefined') SW.Widget = {};

if (typeof(SW.Widget.Spin) == 'undefined') {
  SW.Widget.Spin = {

  convert : function(text) {
    text = SW.DOM.getElement(text);
    if (text == undefined ||
        !text.getAttribute("type") ||
        text.getAttribute("type").toLowerCase() != "text" ||
        text.getAttribute("swWidgetType") != "spin") return;

    var me = SW.Widget.Spin;

    if (SW.Widget._widgets[text.id]) return;
    SW.Widget._widgets[text.id] = true;

    var span = document.createElement('span');
    span.id = 'spin__'+text.id;
    span.className = 'SWspin';
    span.__from = text;
    var elementWidth = SW.DOM.getElementBox(text).x;

    span.innerHTML = '<table cellpadding="0" cellspacing="0"><tr><td class="label"><label></label></td><td class="spin-button"><table cellpadding="0" cellspacing="0"><tr><td class="up">&nbsp;</td></tr><tr><td class="down">&nbsp;</td></tr></table></td></tr></td>';

    var label = SW.DOM.queryElement('label', span);
    var td_up = SW.DOM.queryElement('td.up', span);
    var td_down = SW.DOM.queryElement('td.down', span);

    //text.style.display = 'none';
    text.parentNode.appendChild(span);
    text.__wrapper = span;

    label.appendChild(text);

    if (text.disabled) me.setDisabled(text, true, true);
    if (elementWidth < 50) elementWidth = 50;
    span.style.width = (elementWidth+20)+'px';
    text.style.width = (elementWidth-12)+'px';

    SW.Signal.connect(text, 'onkeydown', null, me.keyDown);
    SW.Signal.connect(text, 'onkeypress', null, me.keyPress);
    SW.Signal.connect(text, 'onchange', null, me.change);

    SW.Signal.connect(td_up, 'onclick', text, me.clickUp);
    SW.Signal.connect(td_down, 'onclick', text, me.clickDown);

    td_up.onmouseover = me.upOver;
    td_up.onmouseout = me.upOut;
    td_down.onmouseover = me.downOver;
    td_down.onmouseout = me.downOut;
  },

  setDisabled : function (text, isDisabled, forceChange) {
    //console.log('SW.Widget.Spin.setDisabled '+text+', '+isDisabled);
	  var myClass = SW.DOM.getClass(text.__wrapper);
    if (isDisabled) {
      if (!text.disabled || forceChange) {
        text.disabled = true;
        myClass.add("SWspin_Disable");
      }
    } else {
      if (text.disabled || forceChange) {
        text.disabled = false;
        myClass.remove("SWspin_Disable");
      }
    }
  },

  keyDown : function (e) {
    if (this.disabled) return;

    var key = e.key();
    //console.log("SW.Widget.Spin.keyDown "+key.code+', string='+key.string);
    if (key.code == 38) this.value++;
    if (key.code == 40 && this.value > 0) this.value--;
    if (/\d/.exec(key.string) ||               // numbers
        key.code == 8 || key.code == 9 ||      // backspace, tab
        (key.code >= 35 && key.code <= 46 && key.code != 38 && key.code != 40) ||  // home, end, arrows, ins, del
        (key.code >= 96 && key.code <= 105))   // NUM_numbers
      return;
    if (e.code == 13) {  // enter
      this.thisform.submit();
      return;
    }
    e.stop();
    SW.Signal.dispatchEvent(this, 'onchange');
  },

  keyPress : function (e) {
    if (this.disabled) return;

    var key = e.key();
    //console.log("SW.Widget.Spin.keyPress "+key.code+', string='+key.string);
    if (/\d/.exec(key.string) ||               // numbers
        key.code == 8 || key.code == 9 ||      // backspace, tab
        (key.code >= 35 && key.code <= 46)) return;
    if (/[A-Za-z\!\@\#\$\%\^\&\*\+\=\-\(\)\`\~\\\/\?\.\,\'\"\{\}\[\]]/.exec(key.string) || key.code > 128) e.stop();
  },

  change : function(e) {
    if (this.disabled) return;

    var text = e.target();
    var v = "";
    for (var i=0; i<text.value.length; i++) {
      if (/\d/.exec(text.value.substr(i, 1))) v = v + text.value.substr(i, 1);
    }
    if (!v.length) v = 0;
    text.value = v;
  },

  clickUp : function (e) {
    if (this.disabled) return;

    this.value++;
    SW.Signal.dispatchEvent(this, 'onchange');
  },

  clickDown : function (e) {
    if (this.disabled) return;

    if (this.value > 0) this.value--;
    SW.Signal.dispatchEvent(this, 'onchange');
  },

  upOver : function (e) {
    //console.log("SW.Widget.Spin.upOver");
    var span = SW.DOM.getParentByTagName('span', this);
    if (span.__from.disabled) return;
    //span.className = 'SWspin SWspin-hlUp';
    var myClass = SW.DOM.getClass(span);
    if (!myClass.exists('SWspin-hlUp')) myClass.add('SWspin-hlUp');
  },

  upOut : function (e) {
    //console.log("SW.Widget.Spin.upOut");
    var span = SW.DOM.getParentByTagName('span', this);
    if (span.__from.disabled) return;
//     span.className = 'SWspin';
    var myClass = SW.DOM.getClass(span);
    if (myClass.exists('SWspin-hlUp')) myClass.remove('SWspin-hlUp');
  },

  downOver : function (e) {
    //console.log("SW.Widget.Spin.downOver");
    var span = SW.DOM.getParentByTagName('span', this);
    if (span.__from.disabled) return;
//     span.className = 'SWspin SWspin-hlDown';
    var myClass = SW.DOM.getClass(span);
    if (!myClass.exists('SWspin-hlDown')) myClass.add('SWspin-hlDown');
  },

  downOut : function (e) {
    //console.log("SW.Widget.Spin.downOut");
    var span = SW.DOM.getParentByTagName('span', this);
    if (span.__from.disabled) return;
//     span.className = 'SWspin';
    var myClass = SW.DOM.getClass(span);
    if (myClass.exists('SWspin-hlDown')) myClass.remove('SWspin-hlDown');
  }

  };
}



// preloader.js

//////////
//
// preloader bar functions 
//
//////////

function getScreenWidth() {
	var result = 2000;

	if (window.innerWidth) {
		// all except Explorer
		result = parseInt(window.innerWidth);
	} else if (document.documentElement && document.documentElement.clientWidth) {
		// Explorer 6 Strict Mode
		result = parseInt(document.documentElement.clientWidth);
	} else if (document.body) {
		// other Explorers
		result = parseInt(document.body.clientWidth);
	}
	if (isNaN(result)) {
		result = 2000;
	}
	return result;
}

function getScreenHeight() {
	var result = 2000;

	if (window.innerHeight) {
		// all except Explorer
		result = parseInt(window.innerHeight);
	} else if (document.documentElement && document.documentElement.clientHeight) {
		// Explorer 6 Strict Mode
		result = parseInt(document.documentElement.clientHeight);
	} else if (document.body) {
		// other Explorers
		result = parseInt(document.body.clientHeight);
	}
	if (isNaN(result)) {
		result = 2000;
	}
	return result;
}

function getScreenOffsetX() {
	var result = 2000;

	if (window.pageXOffset) {
		// all except Explorer
		result = parseInt(window.pageXOffset);
	} else if (document.documentElement && document.documentElement.scrollLeft) {
		// Explorer 6 Strict Mode
		result = parseInt(document.documentElement.scrollLeft);
	} else if (document.body) {
		// other Explorers
		result = parseInt(document.body.scrollLeft);
	}
	if (isNaN(result)) {
		result = 2000;
	}
	return result;
}

function getScreenOffsetY() {
	var result = 2000;

	if (window.innerHeight) {
		// all except Explorer
		result = parseInt(window.pageYOffset);
	} else if (document.documentElement && document.documentElement.scrollTop) {
		// Explorer 6 Strict Mode
		result = parseInt(document.documentElement.scrollTop);
	} else if (document.body) {
		// other Explorers
		result = parseInt(document.body.scrollTop);
	}
	if (isNaN(result)) {
		result = 2000;
	}
	return result;
}

function TogglePreloader(fl) {
	var x,y;
	x = getScreenWidth();
	y = getScreenHeight();
	var iframe=document.getElementById('preloader_iframe');
	var table=document.getElementById('preloader_table');
	var td=document.getElementById('preloader_td');
	var el=document.getElementById('div_desktop');
	if(null!=el) {
		el.style.visibility = (fl==1)?'visible':'hidden';
		el.style.display = (fl==1)?'block':'none';
		el.style.width = x + "px";
		el.style.height = y + "px";
		el.style.zIndex = 1;
	}

	var el=document.getElementById('loader');
	if(null!=el) {
		var top = (y/2) - 50;
		var left = (x/2) - 200;
		if( left<=0 ) left = 10;
		td.style.width = (getScreenWidth() + getScreenOffsetX()) + "px";
		td.style.height = (getScreenHeight() + getScreenOffsetY()) + "px";
		top += getScreenOffsetY();
		left += getScreenOffsetX(); 
		table.style.display=(fl==1)?'block':'none';
		iframe.style.left = left + "px";
		iframe.style.top = top + "px";
		iframe.style.display=(fl==1)?'block':'none';
		el.style.visibility = (fl==1)?'visible':'hidden';
		el.style.display = (fl==1)?'block':'none';
		el.style.left = left + "px"
		el.style.top = top + "px";
	}
}


// slider.js

// slider.js
// Title: tigra slider control

// Description: See the demo at url

// URL: http://www.softcomplex.com/products/tigra_slider_control/

// Version: 1.0.2 (commented source)

// Date: 08/21/2008
// Tech. Support: http://www.softcomplex.com/forum/
// Notes: This script is free. Visit official site for further details.

function slider (a_init, a_tpl) {

	this.f_setValue  = f_sliderSetValue;
	this.f_getPos    = f_sliderGetPos;
	
	// register in the global collection	
	if (!window.A_SLIDERS)
		window.A_SLIDERS = [];
	this.n_id = window.A_SLIDERS.length;
	window.A_SLIDERS[this.n_id] = this;

	// save config parameters in the slider object
	var s_key;
	if (a_tpl)
		for (s_key in a_tpl)
			this[s_key] = a_tpl[s_key];
	for (s_key in a_init)
		this[s_key] = a_init[s_key];

	this.n_pix2value = this.n_pathLength / (this.n_maxValue - this.n_minValue);
	if (this.n_value == null)
		this.n_value = this.n_minValue;

	// generate the control's HTML
	document.write(
			'<div onmousedown="return f_sliderMouseDown(' + this.n_id + ')" style="width:' + this.n_controlWidth + 'px;height:' + this.n_controlHeight + 'px;border:0; background:url(' + this.s_imgControl + ') center no-repeat; margin-left:-12px" id="sl' + this.n_id + 'base">' +
			'<div class="sliderGlow" style="background:url(' + this.s_imgGlow + ') 12px center no-repeat;width:' + this.n_pathLeft + 'px;height:' + this.n_controlHeight + 'px;border:0;" id="sl' + this.n_id + 'glow">' +
			'<img src="' + this.s_imgSlider + '" width="' + this.n_sliderWidth + '" height="' + this.n_sliderHeight + '" border="0" style="position:relative;left:' + this.n_pathLeft + 'px;top:' + this.n_pathTop + 'px;z-index:' + this.n_zIndex + ';cursor:pointer;visibility:hidden;" name="sl' + this.n_id + 'slider" id="sl' + this.n_id + 'slider" onmousedown="return f_sliderMouseDown(' + this.n_id + ')"/></div></div>'
	);
	this.e_base   = get_element('sl' + this.n_id + 'base');
	this.e_slider = get_element('sl' + this.n_id + 'slider');
	this.e_glow = get_element('sl' + this.n_id + 'glow');
	
	// safely hook document/window events
	if (!window.f_savedMouseMove && document.onmousemove != f_sliderMouseMove) {
		window.f_savedMouseMove = document.onmousemove;
		document.onmousemove = f_sliderMouseMove;
	}
	if (!window.f_savedMouseUp && document.onmouseup != f_sliderMouseUp) {
		window.f_savedMouseUp = document.onmouseup;
		document.onmouseup = f_sliderMouseUp;
	}
	// preset to the value in the input box if available
	var e_input = this.s_form == null
		? get_element(this.s_name)
		: document.forms[this.s_form]
			? document.forms[this.s_form].elements[this.s_name]
			: null;
	this.f_setValue(e_input && e_input.value != '' ? e_input.value : null, 1);
	this.e_slider.style.visibility = 'visible';
}

function f_sliderSetValue (n_value, b_noInputCheck) {
	if (n_value == null)
		n_value = this.n_value == null ? this.n_minValue : this.n_value;
	if (isNaN(n_value))
		return false;
	// round to closest multiple if step is specified
	if (this.n_step)
		n_value = Math.round((n_value - this.n_minValue) / this.n_step) * this.n_step + this.n_minValue;
	// smooth out the result
	if (n_value % 1)
		n_value = Math.round(n_value * 1e5) / 1e5;

	if (n_value < this.n_minValue)
		n_value = this.n_minValue;
	if (n_value > this.n_maxValue)
		n_value = this.n_maxValue;

	this.n_value = n_value;

	// move the slider
	if (this.b_vertical)
		this.e_slider.style.top  = (this.n_pathTop + this.n_pathLength - Math.round((n_value - this.n_minValue) * this.n_pix2value)) + 'px';
	else
		var s_position = this.n_pathLeft + Math.round((n_value - this.n_minValue) * this.n_pix2value);
		this.e_slider.style.left = (s_position) + 'px';
		g_position = s_position + 4;
		this.e_glow.style.width = g_position + 'px';
	

	// save new value
	var e_input;
	if (this.s_form == null) {
		e_input = get_element(this.s_name);
		if (!e_input)
			return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the input with ID='" + this.s_name + "'.");
	}
	else {
		var e_form = document.forms[this.s_form];
		if (!e_form)
			return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the form with NAME='" + this.s_form + "'.");
		e_input = e_form.elements[this.s_name];
		if (!e_input)
			return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the input with NAME='" + this.s_name + "'.");
	}
	e_input.value = n_value;
	
	this.m_onchange();
//	alert("2");	
}

// get absolute position of the element in the document
function f_sliderGetPos (b_vertical, b_base) {
	var n_pos = 0,
		s_coord = (b_vertical ? 'Top' : 'Left');
	var o_elem = o_elem2 = b_base ? this.e_base : this.e_slider;
	
	while (o_elem) {
		n_pos += o_elem["offset" + s_coord];
		o_elem = o_elem.offsetParent;
	}
	o_elem = o_elem2;

	var n_offset;
	while (o_elem.tagName != "BODY") {
		n_offset = o_elem["scroll" + s_coord];
		if (n_offset)
			n_pos -= o_elem["scroll" + s_coord];
		o_elem = o_elem.parentNode;
	}
	return n_pos;
}

function f_sliderMouseDown (n_id) {
	window.n_activeSliderId = n_id;
	return false;
}

function f_sliderMouseUp (e_event, b_watching) {
	if (window.n_activeSliderId != null) {
		var o_slider = window.A_SLIDERS[window.n_activeSliderId];
		o_slider.f_setValue(o_slider.n_minValue + (o_slider.b_vertical
			? (o_slider.n_pathLength - parseInt(o_slider.e_slider.style.top) + o_slider.n_pathTop)
			: (parseInt(o_slider.e_slider.style.left) - o_slider.n_pathLeft)) / o_slider.n_pix2value);
		if (b_watching)	return;
		f_sliderMouseMove (e_event);
		window.n_activeSliderId = null;
	}
	if (window.f_savedMouseUp)
		return window.f_savedMouseUp(e_event);
}

function f_sliderMouseMove (e_event) {

	if (!e_event && window.event) e_event = window.event;

	// save mouse coordinates
	if (e_event) {
		window.n_mouseX = e_event.clientX + f_scrollLeft();
		window.n_mouseY = e_event.clientY + f_scrollTop();
	}

	// check if in drag mode
	if (window.n_activeSliderId != null) {
		var o_slider = window.A_SLIDERS[window.n_activeSliderId];

		var n_pxOffset;
		if (o_slider.b_vertical) {
			var n_sliderTop = window.n_mouseY - o_slider.n_sliderHeight / 2 - o_slider.f_getPos(1, 1) - 3;
			// limit the slider movement
			if (n_sliderTop < o_slider.n_pathTop)
				n_sliderTop = o_slider.n_pathTop;
			var n_pxMax = o_slider.n_pathTop + o_slider.n_pathLength;
			if (n_sliderTop > n_pxMax)
				n_sliderTop = n_pxMax;
			o_slider.e_slider.style.top = n_sliderTop + 'px';
			n_pxOffset = o_slider.n_pathLength - n_sliderTop + o_slider.n_pathTop;
		}
		else {
			var n_sliderLeft = window.n_mouseX - o_slider.n_sliderWidth / 2 - o_slider.f_getPos(0, 1) - 3;
			// limit the slider movement
			if (n_sliderLeft < o_slider.n_pathLeft)
				n_sliderLeft = o_slider.n_pathLeft;
			var n_pxMax = o_slider.n_pathLeft + o_slider.n_pathLength;
			if (n_sliderLeft > n_pxMax)
				n_sliderLeft = n_pxMax;
			o_slider.e_slider.style.left = n_sliderLeft + 'px';
			n_pxOffset = n_sliderLeft - o_slider.n_pathLeft;
		}
		if (o_slider.b_watch)
			 f_sliderMouseUp(e_event, 1);

		return false;
	}
	
	if (window.f_savedMouseMove)
		return window.f_savedMouseMove(e_event);
}

// get the scroller positions of the page
function f_scrollLeft() {
	return f_filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function f_scrollTop() {
	return f_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}

function f_sliderError (n_id, s_message) {
	alert("Slider #" + n_id + " Error:\n" + s_message);
	window.n_activeSliderId = null;
}

get_element = document.all ?
	function (s_id) { return document.all[s_id] } :
	function (s_id) { return document.getElementById(s_id) };




if (typeof(SW.settings) == 'undefined') SW.settings = {};

SW.settings.loginMask = '^[A-Za-z0-9]{1}[A-Za-z0-9_\.\-]{0,1000}$';
SW.settings.loginAlert = 'Login Name is incorrect. Please make sure that your Login Name is 5 to 20 characters long and does not contain special or national characters';


