// Z 

function Z ()
{
this.arguments = arguments;
this.test = 'TEST_OK';

this.GetCSS = function (selector)
{
var sheets = document.styleSheets;
var rules = [];
if (sheets)
{
for (var i=0; i<sheets.length; i++)
{
rules = sheets[i].cssRules || sheets[i].rules;
for (var j=0; j<rules.length; j++)
{
if (rules[j].selectorText == selector)
{
return rules[j];
}
}
}
}
}

this.GetItself = function ()
{
if (window.z == undefined)
{
window.z = new Z('.');
}
return window.z;
}

this.Handler = function (arguments)
{
data = arguments[0];
arg0 = arguments[0];
if (arg0 == undefined)
{
return this.GetItself();
}
else if (typeof(data) == 'object')
{
obj = data;
}
else if (typeof(data) == 'string')
{
if (m = data.match(/^(\+)(\w+)$/))
{
obj = arguments[1] ? this.DeployElement(m[2],arguments[1]) : document.createElement(m[2]); //obj = document.createElement(m[2]);
}
else if (data.length > 0)
{
obj = document.getElementById(data);
}
}
if (navigator.userAgent.search(/MSIE/) != -1)
{
for (prop in Element.prototype)
{
if (obj[prop] == undefined)
{
obj[prop] = Element.prototype[prop];
}
}
}
return obj;
}

this.Init = function ()
{
window.on = Element.prototype.on;
window.onEvent = Element.prototype.onEvent;
window.getScrollTop = function () { return document.body.scrollTop ? document.body.scrollTop+window.innerHeight : window.pageYOffset+window.innerHeight; };
}

this.DeployElement = function (tag, info)
{
var elem = Z('+'+tag);
for (attr in info)
{
if ((attr != 'tag') && (attr != 'className') && (attr != 'content') && (attr != 'children') && (info[attr] != null))
{
elem.setAttribute(attr,info[attr]);
}
}
if (info.className)
{
elem.className = info.className;
}
if (info.children) // .tag задаёт тег. ключ к ассоц-массиву нельзя было пользовать т.к могут быть одинаковые элементы 
{
for (i=0; i<info.children.length; i++)
{
elem.appendChild(this.DeployElement(info.children[i].tag,info.children[i]));
}
}
if (info.content)
{
elem.appendChild(document.createTextNode(info.content));
}
if (info.parent)
{
info.parent.appendChild(elem);
}
return elem;
}

if (arguments[0] != '.')
{
return this.Handler(arguments);
}
}

$ = Z; // jquery conflict

function ago (seconds)
{
return time()-seconds;
}

function str (path, value)
{
this.Get = function (path)
{
var nodes = path.split('.');
var cur = window.lng;
//alert(window.lng.cart);
for (var i=0; i<nodes.length; i++)
{//alert('window.lng.'+nodes[i]+'='+cur[nodes[i]]);
cur = cur[nodes[i]];
if (typeof(cur) != 'object')
{
break;
}
}
return cur;
}

this.Set = function (path, value)
{
var nodes = path.split('.');
if (window.lng == undefined) window.lng = {};
var cur_path = [];
for (var i=0; i<nodes.length; i++)
{
cur_path.push(nodes[i]);
full_path = 'window.lng.'+cur_path.join('.');
eval('if ('+full_path+' == undefined) '+full_path+' = {};');
}
eval(full_path+' = value;');
}

return (value != undefined) ? this.Set(path,value) : this.Get(path);
}

function time ()
{
var d = new Date();
return parseInt(d.getTime()/1000);
}

if (navigator.userAgent.search(/MSIE/) != -1)
{
var Element = {};
Element.prototype = {};
}

Element.prototype.addClass = function (name)
{
this.removeClass(name); // prevent dupes
this.className += ' '+name;
}

Element.prototype.appendBefore = function (p_node)
{
p_node.parentNode.insertBefore(this,p_node);
return this;
}

Element.prototype.appendTo = function (p_node)
{
p_node.appendChild(this);
return this;
}

Element.prototype.getID = function ()
{
if (this.getAttribute('id') == undefined)
{
this.setAttribute('id','auto_'+Math.rand(100000,100000000));
}
return this.getAttribute('id');
}

Element.prototype.getCSS = function (property)
{
if (this.currentStyle)
{
return this.currentStyle[property];
}
else if (window.getComputedStyle)
{
return document.defaultView.getComputedStyle(this,null).getPropertyValue(property);
}
};

Element.prototype.getOffsetLeft = function ()
{
return (this.offsetParent ? Z(this.offsetParent).getOffsetLeft() : 0)+this.offsetLeft;
}

Element.prototype.getOffsetTop = function ()
{
return (this.offsetParent ? Z(this.offsetParent).getOffsetTop() : 0)+this.offsetTop;
}

Element.prototype.getPoint = function (i)
{
x = this.getOffsetLeft();
y = this.getOffsetTop();
w = this.offsetWidth;
h = this.offsetHeight;
switch (i)
{
case 1: return [x,y];
case 2: return [x+w,y];
case 3: return [x+w,y+h];
case 4: return [x,y+h];
}
}

Element.prototype.hide = function ()
{
this.style.display = 'none';
}

Element.prototype.isEmpty = function ()
{
return (this.innerHTML.length > 0);
}



Element.prototype.on = function (event, handler)
{
if (typeof(event) == 'object') // list of events
{
for (var i=0; i<event.length; i++)
{
this.onEvent(event[i],handler);
}
}
else
{
this.onEvent(event,handler);
}
}

Element.prototype.onEvent = function (event, handler)
{
if (this.addEventListener)
{
this.addEventListener(event,handler,false);
}
else
{
eval('this.on'+event+' = handler');
}
}

Element.prototype.parentTag = function (name)
{
name = name.toUpperCase();
var cur = this;
while (cur.parentNode)
{
if (cur.tagName == name)
{
return cur;
}
cur = cur.parentNode;
}
}

Element.prototype.load = function (uri, callback)
{
this.ds_callback = function (data) { this.innerHTML = data; }
this.ds = new DataSource('raw',uri,new Callback(this,'ds_callback'));
this.ds.Get();
}

Element.prototype.removeClass = function (name)
{
this.className = this.className.replace(new RegExp('(^|\s)'+name+'(\s|$)','i'),'');
}

Element.prototype.ShowOnScroll = function ()
{
var marker = Z('+div').appendBefore(this);
Z(window).on('scroll',new Function('','if (window.getScrollTop() >= Z("'+marker.getID()+'").getOffsetTop()) Z("'+this.getID()+'").show();'));
}

Element.prototype.show = function (point)
{
this.style.display = 'block';
if (point != undefined)
{
this.style.left = point[0]+'px';
this.style.top = point[1]+'px';
}
}

Element.prototype.toggle = function ()
{
this.style.display = (CLR.GetCSSValue(this,'display') == 'none') ? 'block' : 'none';
}

Math.rand = function (min, max)
{
return this.round(min+(max-min)*this.random());
};

String.prototype.rxval = function (rx, i)
{
return (m = this.match(rx)) ? m[i] : '';
};

String.prototype.template = function (values)
{
var str = this;
for (key in values)
{
str = str.replace(new RegExp('\{'+key+'\}','gi'),values[key]);
}
return str;
};

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

// ============================================================================

document.cookies = new Object();
document.cookies.get = function (name)
{
var arr = document.cookie.split(';');
var item;
for (var i=0; i<arr.length; i++)
{
item = arr[i].split('=',2);
if (item[0].trim() == name)
{
return decodeURIComponent(item[1]);
}
}
return '';
};

document.cookies.set = function (name, value, expires)
{
var str = name+'='+value;
if (expires)
{
var date = new Date();
date.setTime(date.getTime()+(expires*1000));
str += '; expires='+date.toGMTString();
}
str += '; path=/';
document.cookie = str;
};

// ============================================================================

function Callback (object, method)
{
this.__construct = function (object, method)
{
this.object = object;
this.method = eval('object.'+method);
}

this.call = function (args)
{
args = (args != undefined) ? args : [];
return this.method.apply(this.object,args);
}

this.__construct(object, method);
}

// ============================================================================

function DataSource (type, uri, callback)
{
this.__construct = function (type, uri, callback)
{
this.type = type;
this.baseurl = ((m = document.location.toString().match(/^\w+\:\/\/[^\/]+/)) ? m[0] : document.location.toString());
this.uri = uri;
this.callback = callback;
this.http = new XMLHttpRequest();
this.http.owner = this;
}

this.Get = function ()
{
this.http.open('GET',this.baseurl+this.uri,true);
this.http.onreadystatechange = function () { if ((this.readyState == 4) && (this.status == 200)) this.owner.OnData(this.responseText); }
this.http.send(null);
}

this.OnData = function (raw)
{
var data;
//$('debug').value = raw;
if (this.type == 'json')
{
eval('data = '+raw+';');
}
else
{
data = raw;
}
this.callback.call([data]);
}

this.Post = function (data)
{
var buf = '';
for (var key in data)
{
buf += '&'+key+'='+encodeURIComponent(data[key]);
}
data = buf.substr(1);
this.http.open('POST',this.baseurl+uri,true);
this.http.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=Windows-1251'); // ; charset=Windows-1251
this.http.setRequestHeader('Content-Length',data.length);
this.http.setRequestHeader('Connection','close');
this.http.onreadystatechange = function () { if ((this.readyState == 4) && (this.status == 200)) this.owner.OnData(this.responseText); }
this.http.send(data);
}

this.__construct(type, uri, callback);
}

// ============================================================================

function DataExchange ()
{
this.__construct = function ()
{
this.ready = true;
this.baseurl = ((m = document.location.toString().match(/^\w+\:\/\/[^\/]+/)) ? m[0] : document.location.toString());
this.http = new XMLHttpRequest();
this.http.owner = this;
}

this.EncodePostData = function (obj)
{
var buf = '';
for (var key in obj)
{
buf += '&'+key+'='+encodeURIComponent(obj[key]);
}
return buf.substr(1);
}

this.Get = function (uri, callback)
{
if (this.ready)
{
this.ready = false;
this.callback = callback;
this.http.open('GET',this.baseurl+uri,true);
this.http.onreadystatechange = function () { this.owner.OnReadyStateChange() };
this.http.send(null);
}
}

this.OnDataReceived = function (response_text)
{//alert(response_text);
this.callback.call([JSON.parse(response_text.replace(/^[^\{\[]+/,''))]);
this.ready = true;
}

this.OnReadyStateChange = function ()
{
if ((this.http.readyState == 4) && (this.http.status == 200))
{
this.OnDataReceived(this.http.responseText);
}
}

this.Post = function (uri, data, callback)
{
if (this.ready)
{
this.ready = false;
this.callback = callback;
data = this.EncodePostData(data);
this.http.open('POST',this.baseurl+uri,true);
this.http.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); // ; charset=Windows-1251
this.http.setRequestHeader('Content-Length',data.length);
this.http.setRequestHeader('Connection','close');
this.http.onreadystatechange = function () { this.owner.OnReadyStateChange() };
this.http.send(data);
}
}

this.__construct();
}

// ============================================================================



// Дата для форм

function DateInput (name, value, args)
{
this.__construct = function (name, value, args)
{
this.name = name;
this.args = args;
this.box = Z(name+'_box');

var onchange = function () { this.control.Update(); }

// input
this.input = document.createElement('input');
this.input.setAttribute('type','hidden');
this.input.setAttribute('name',name);
this.input.setAttribute('value',value);
this.box.appendChild(this.input);

// day
this.day = document.createElement('select');
this.day.appendChild(this.createOptionElement(0,''));
for (var i=1; i<=31; i++)
{
this.day.appendChild(this.createOptionElement(i,i));
}
this.box.appendChild(this.day);
this.day.control = this;
this.day.onchange = onchange;

// month
var strmonths = ['','января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря'];
this.month = document.createElement('select');
this.month.appendChild(this.createOptionElement(0,''));
for (var i=1; i<=12; i++)
{
this.month.appendChild(this.createOptionElement(i,strmonths[i]));
}
this.box.appendChild(this.month);
this.month.control = this;
this.month.onchange = onchange;

// year
this.year = document.createElement('select');
this.year.appendChild(this.createOptionElement(0,''));
for (var i=this.args.max_year; i>=this.args.min_year; i--)
{
this.year.appendChild(this.createOptionElement(i,i));
}
this.box.appendChild(this.year);
this.year.control = this;
this.year.onchange = onchange;

// time
if (this.args.time)
{
this.box.appendChild(document.createTextNode(' Время: '));


// hours
this.hours = document.createElement('select');
for (var i=0; i<=23; i++)
{
this.hours.appendChild(this.createOptionElement(i,i.toString().replace(/^(\d)$/,'0$1')));
}
this.box.appendChild(this.hours);
this.hours.control = this;
this.hours.onchange = onchange;

// div
this.box.appendChild(document.createTextNode(':'));

// minutes
this.minutes = document.createElement('select');
for (var i=0; i<=45; i+=15)
{
this.minutes.appendChild(this.createOptionElement(i,i.toString().replace(/^(\d)$/,'0$1')));
}
this.box.appendChild(this.minutes);
this.minutes.control = this;
this.minutes.onchange = onchange;

}

this.Set(value);
}

this.createOptionElement = function (value, title)
{
var elem = document.createElement('option');
elem.setAttribute('value',value);
elem.appendChild(document.createTextNode(title));
return elem;
}

this.Set = function (unixtime)
{
if (unixtime)
{
date = new Date(unixtime*1000);

this.day.value = date.getDate();
this.month.value = date.getMonth()+1;
this.year.value = date.getFullYear();
if (this.args.time)
{
this.hours.value = date.getHours();
this.minutes.value = date.getMinutes();
//this.time.innerHTML = date.getHours()+':'+('0'+date.getMinutes()).replace(/.*(\d{2})$/,'$1');
}

this.input.value = Math.round(date.getTime()/1000);
}
else
{
//this.day.value = 0;
//this.month.value = 0;
//this.year.value = 0;

this.input.value = 0;
}
}

this.Update = function ()
{
if ((this.day.value != 0) && (this.month.value != 0) && (this.year.value != 0))
{
date = new Date();
date.setDate(this.day.value);
date.setMonth(this.month.value-1);
date.setFullYear(this.year.value);
if (this.args.time)
{//alert(this.hours.value+':'+this.minutes.value);
date.setHours(this.hours.value);
date.setMinutes(this.minutes.value);
}
this.Set(Math.round(date.getTime()/1000));
}
else
{
this.Set(0);
}
}

this.__construct(name,value,args);
}

// ============================================================================
// День для форм (value: "0324")

function DayInput (name, value)
{
this.__construct = function (name, value)
{
this.box = Z(name+'_box');
this.date = {month: parseInt(value.toString().substr(0,2)), day: parseInt(value.toString().toString().substr(2,2))};

// input
this.input = document.createElement('input');
this.input.setAttribute('type','hidden');
this.input.setAttribute('name',name);
this.input.setAttribute('value',value);
this.box.appendChild(this.input);

// day
this.day = document.createElement('select');
for (var i=1; i<=31; i++)
{
this.day.appendChild(this.createOptionElement(i,i));
}
this.box.appendChild(this.day);
this.day.control = this;
this.day.onchange = function () { this.control.date.day = this.value; this.control.Update(); }

// month
var strmonths = ['','января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря'];
this.month = document.createElement('select');
for (var i=1; i<=12; i++)
{
this.month.appendChild(this.createOptionElement(i,strmonths[i]));
}
this.box.appendChild(this.month);
this.month.control = this;
this.month.onchange = function () { this.control.date.month = this.value; this.control.Update(); }

this.Update();
}

this.createOptionElement = function (value, title)
{
var elem = document.createElement('option');
elem.setAttribute('value',value);
elem.appendChild(document.createTextNode(title));
return elem;
}

this.Update = function ()
{
this.day.value = this.date.day;
this.month.value = this.date.month;
this.input.value = (this.date.month<10?'0':'')+this.date.month+(this.date.day<10?'0':'')+this.date.day;
}

this.__construct(name,value);
}

// ============================================================================
// Flags Manager

function FlagsInput (id, flags)
{
this.__construct = function (id, flags)
{
this.object = Z(id);
this.flags = flags;
this.items = {};

//var onchange = function () { this.control.Update(); }

// container
this.Deploy();
this.Parse();
}

this.Deploy = function ()
{
this.container = document.createElement('div');
this.container.className = 'flags_input';
this.object.parentNode.insertBefore(this.container,this.object);
this.object.style.display = 'none';

for (var key in this.flags)
{
this.AddFlag(key,this.flags[key]);
}
}

this.AddFlag = function (key, title)
{
var id = this.object.name+'_'+key;

// box
var item = document.createElement('input');
item.setAttribute('type','checkbox');
item.setAttribute('id',id);
item.control = this;
this.container.appendChild(item);
item.on('change',function () { this.cheked = true; this.control.Update(); });

// label
var label = document.createElement('label');
label.setAttribute('for',id);
label.appendChild(document.createTextNode(title));
this.container.appendChild(label);

this.items[key] = { item: item, label: label };

//this.Update();
}

this.Parse = function ()
{
var selected = this.object.value.split(',');
for (var i=0; i<selected.length; i++)
{
if (this.items[selected[i]])
{
this.items[selected[i]].item.checked = true;
}
}
}

this.Update = function ()
{
var selected = [];
for (var key in this.flags)
{
if (this.items[key] && this.items[key].item.checked)
{
selected.push(key);
}
}
this.object.value = selected.join(',');
}

this.__construct(id, flags);
}

// ============================================================================

function ItemsHistory ()
{
this.__construct = function ()
{
this.Load();
}

this.AddItem = function (id)
{
if (this.FindItem(id) == -1)
{
this.items.push(id);
if (this.items.length > 50)
{
this.items.shift();
}
this.Save();
}
}

this.FindItem = function (id)
{
for (var i=0; i<this.items.length; i++)
{
if (this.items[i] == id)
{
return i;
}
}

return -1;
}

this.Load = function ()
{
var s = document.cookies.get('recent_items').toString();
this.items = (s.search(/^\d+(\,\d+)*$/) != -1) ? s.split(',') : [];
}

this.Save = function ()
{
document.cookies.set('recent_items',this.items.join(','),86400*365);
}

this.__construct();
}

// ============================================================================

function LiveBox (id)
{
this.__construct = function (id)
{
this.baseurl = ((m = document.location.toString().match(/^\w+\:\/\/[^\/]+/)) ? m[0] : document.location.toString());
this.target = Z(id);
this.http = new XMLHttpRequest();
this.http.owner = this;
this.ready = true;
}

this.Update = function (uri)
{
if (this.ready)
{
this.ready = false;
this.http.open('GET',this.baseurl+uri,false);
this.http.onreadystatechange = function () { if ((this.readyState == 4) && (this.status == 200)) this.owner.OnUpdate(this.responseText); }
this.http.send(null);
}
}

this.OnUpdate = function (text)
{
this.target.innerHTML = text;
this.ready = true;
}

this.__construct(id);
}

// ============================================================================
// Класс для списка получателей

function ReceiversInput (id, args)
{
this.__construct = function (id, args)
{
this.object = Z(id);
this.args = args;
this.items = {};
this.i = 0;

this.Deploy();
this.Parse();

if (this.args.required && (this.GetItemsCount() == 0))
{
this.AppendItem();
}
}

this.AppendItem = function ()
{
var i = this.i++;
this.items[i] = new ReceiversInputItem(this);
this.Update();
return this.items[i];
}

this.Deploy = function ()
{
this.object.style.display = 'none';

// container
this.container = document.createElement('div');
this.container.className = 'receivers_input';
this.object.parentNode.insertBefore(this.container,this.object);

// head
this.head = document.createElement('div');
this.head.className = 'head';
this.head_1 = document.createElement('div');
this.head_1.className = 'address';
this.head_1.appendChild(document.createTextNode('E-mail'));
this.head.appendChild(this.head_1);
this.head_2 = document.createElement('div');
this.head_2.className = 'ident';
this.head_2.appendChild(document.createTextNode('Имя'));
this.head.appendChild(this.head_2);
this.container.appendChild(this.head);

// itemsbox
this.itemsbox = document.createElement('div');
this.container.appendChild(this.itemsbox);

// append button
this.append = document.createElement('input');
this.append.control = this;
this.append.className = 'button small add';
this.append.setAttribute('type','button');
this.append.setAttribute('value','Добавить');
this.container.appendChild(this.append);
this.append.onclick = function () { this.control.AppendItem(); };
}

this.DropItem = function (i)
{
this.items[i].Drop();
this.items[i] = null;
}

this.GetItemsCount = function ()
{
return this.itemsbox.childNodes.length;
}

this.Parse = function ()
{
var s = this.object.value.replace(/\r/g,'').split("\n");
for (var i=0; i<s.length; i++)
{
if (m = s[i].match(/^(.+?)\s(\S+)$/))
{
this.AppendItem().Set(m[2],m[1]);
}
}
}

this.Update = function ()
{
out = '';
for (i in this.items)
{
if (this.items[i].address.value.length)
{
out += this.items[i].Release()+"\n";
}
}
this.object.value = out;
this.head.style.display = (this.GetItemsCount() > 0) ? 'block' : 'none';
}

this.__construct(id, args);
}

// ============================================================================

function ReceiversInputItem (list)
{
this.__construct = function (list)
{
this.list = list;
this.parent = list.itemsbox;

this.Deploy();
}

this.Deploy = function ()
{
// container
this.container = document.createElement('div');
this.container.className = 'item';
this.parent.appendChild(this.container);

// address
this.address = document.createElement('input');
this.address.control = this;
this.address.className = 'address';
this.container.appendChild(this.address);
this.address.onchange = function () { this.control.list.Update(); };

// title
this.title = document.createElement('input');
this.title.control = this;
this.title.className = 'title';
this.container.appendChild(this.title);
this.title.onchange = function () { this.control.list.Update(); };

// drop
this.drop = document.createElement('input');
this.drop.control = this;
this.drop.className = 'button small delete';
this.drop.setAttribute('type','button');
this.drop.setAttribute('value','Удалить');
this.container.appendChild(this.drop);
this.drop.onclick = function () { this.control.Drop(); }
}

this.Drop = function ()
{
this.Set('','');
this.parent.removeChild(this.container);
this.list.Update();
}

this.Release = function ()
{
return this.title.value+' '+this.address.value;
}

this.Set = function (address, title)
{
this.address.value = address;
this.title.value = title;
}

this.__construct(list);
}

// ============================================================================

function ServiceFunction (callback, interval)
{
this.__construct = function (callback, interval)
{
this.id = 'iterator_'+Math.round(Math.random()*1000000);
this.callback = callback;
this.interval = interval;
window[this.id] = this;
this.Next();
this.Start();
}

this.Start = function ()
{
if (!this.timer)
{
this.timer = window.setInterval(new Function('','window.'+this.id+'.Next();'),this.interval);
}
}

this.Stop = function ()
{
if (this.timer)
{
window.clearInterval(this.timer);
}
}

this.Next = function ()
{
this.callback.call();
}

this.__construct(callback, interval);
}

// ============================================================================

function Trigger (match, hit, args) // call "match" callback, if it's returns true call "hit" callback
{
this.__construct = function (match, hit, args) // args: interval, tolerance
{
this.match = match;
this.hit = hit;
this.args = args || {};
this.value = this.match.call();

this.args.interval = this.args.interval || 100;
this.args.tolerance = this.args.tolerance || 0;

this.watcher = new ServiceFunction(new Callback(this,'Watch'),this.args.interval);
}

this.Watch = function ()
{
var value = this.match.call();
if (value != this.value)
{
this.value = value;
this.hitpoint = time()+this.args.tolerance;
}
if (this.hitpoint && (time() > this.hitpoint))
{
this.hit.call();
this.hitpoint = 0;
}
}

this.__construct(match, hit, args);
}

// ============================================================================

function AddOptionToSelect (id)
{
var sel, title, option;
sel = Z(id);
if (title = window.prompt('Название'))
{
option = document.createElement('option');
option.text = title;
option.value = title;
try
{
sel.add(option, null);
}
catch (e)
{
sel.add(option);
}
sel.selectedIndex = sel.length-1;
}
}

// ============================================================================

Z().Init();
function Cart2Panel (container, args)
{
this.__construct = function (container, args)
{
this.container = container;
this.args = args;
this.profile = {items:{},items_count:0,total_cost:0};
this.panels = {};

this.Deploy();
}

this.Checkout = function ()
{
window.location = this.ui.label.getAttribute('href');
}

this.Clear = function ()
{
for (id in this.profile.items)
{
this.Set(id,0);
}
}

this.CreateUI = function (c)
{
$(c).addClass('cart_panel');

this.ui = {};

this.ui.label = document.createElement('a');
this.ui.label.className = 'cart_label';
this.ui.label.setAttribute('href','/users/cart/show/');
this.ui.label.appendChild(document.createTextNode('Корзина:'));
c.appendChild(this.ui.label);

this.ui.items_count = document.createElement('span');
this.ui.items_count.className = 'items_count';
c.appendChild(this.ui.items_count);

this.ui.total_cost = document.createElement('span');
this.ui.total_cost.className = 'total_cost';
c.appendChild(this.ui.total_cost);
$(this.ui.total_cost).hide();

this.UpdateUI(true);
}

this.Deploy = function ()
{
this.LoadProfile();

this.DeployItself();
this.DeployItemsPanels();
}

this.DeployItself = function ()
{
window.cart = this;

this.CreateUI(this.container);
}

this.DeployItemsPanels = function ()
{
$(function () {
$('.cart_item_panel').each(function (i, elem) { new CartItemPanel(this); });
});
}

this.LoadProfile = function ()
{
this.profile.items = {};
this.profile.items_count = 0;
this.profile.total_cost = 0;

// read cookie "cart_items" ("id1:amount,id2:amount") 
var cart_items_str = document.cookies.get('cart_items');
var cart_items_arr = cart_items_str.split(',');
for (var i=0; i<cart_items_arr.length; i++)
{
if (m = cart_items_arr[i].match(/^(\d{1,10})\:(\d{1,3})$/))
{
this.profile.items[m[1]] = m[2];
this.profile.items_count++;
}
}

// read cookie "cart_total_cost"
var cart_total_cost_str = document.cookies.get('cart_total_cost');
this.profile.total_cost = parseFloat(cart_total_cost_str);
}

this.OutputUnits = function (num, units)
{
//var prefix = num.toString().substr(0,1);
var suffix = num.toString().substr(-1);
//alert(suffix);

if (((num >= 10) && (num <= 14)) || (suffix == 0) || (suffix >= 5))
{
return num+' '+units[2]; // товаров
}
else if ((suffix >= 2) && (suffix <= 4))
{
return num+' '+units[1]; // товара
}
else
{
return num+' '+units[0]; // товар
}
}

this.RegisterItemPanel = function (id, obj)
{
this.panels[id] = obj;
}

this.SaveProfile = function ()
{
var cart_items_arr = [];
for (var id in this.profile.items)
{
if (amount = this.profile.items[id])
{
cart_items_arr.push(id+':'+amount);
}
}
var cart_items_str = cart_items_arr.join(',');

document.cookies.set('cart_items',cart_items_str,86400*365);
document.cookies.set('cart_items_count',this.profile.items_count,86400*365);
}

this.Set = function (id, new_amount)
{
if (new_amount > 0)
{
if (!this.profile.items[id])
{
this.profile.items_count++;
}
this.profile.items[id] = new_amount;
}
else if (this.profile.items[id])
{
delete this.profile.items[id];
this.profile.items_count--;
}

this.Update();
if (this.panels[id])
{
this.panels[id].Update();
}

this.SaveProfile();
}

this.Update = function ()
{
this.UpdateUI();
}

this.UpdateUI = function (lazy)
{
if (!lazy && (window.location.toString().search(/\/users\/cart\/show\//i) != -1))
{
window.location = '/users/cart/show/?nc='+Math.random();
}

this.ui.items_count.innerHTML = this.profile.items_count ? this.OutputUnits(this.profile.items_count,['товар','товара','товаров']) : 'нет товаров';
this.ui.total_cost.innerHTML = this.profile.total_cost+'&nbsp;p.';
}

this.__construct(container, args);
}

function CartItemPanel (container) // args: price, max
{
this.__construct = function (container)
{
this.container = container;
this.cart = window.cart;

this.Deploy();
}

this.CreateUI = function (c)
{
$(c).addClass('cart_item_panel');

this.ui = {};

this.ui.add_btn = document.createElement('a');
this.ui.add_btn.setAttribute('href','javascript:void(0);');
this.ui.add_btn.controller = this;
this.ui.add_btn.className = 'add_btn';
this.ui.add_btn.appendChild(document.createTextNode('В корзину'));
c.appendChild(this.ui.add_btn);
$(this.ui.add_btn).bind('click',function () { this.controller.OnAdd(); });

this.ui.amount_input = document.createElement('span');
//this.ui.amount_input.setAttribute('type','text');
this.ui.amount_input.controller = this;
this.ui.amount_input.className = 'amount_input';
c.appendChild(this.ui.amount_input);
$(this.ui.amount_input).bind('click',function () { this.controller.OnSetAmount(); });

this.ui.checkout_btn = document.createElement('a');
this.ui.checkout_btn.setAttribute('href','javascript:void(0);');
this.ui.checkout_btn.controller = this;
this.ui.checkout_btn.className = 'checkout_btn';
this.ui.checkout_btn.appendChild(document.createTextNode('Оформить заказ'));
c.appendChild(this.ui.checkout_btn);
$(this.ui.checkout_btn).bind('click',function () { this.controller.OnCheckout(); });

this.ui.remove_btn = document.createElement('a');
this.ui.remove_btn.setAttribute('href','javascript:void(0);');
this.ui.remove_btn.controller = this;
this.ui.remove_btn.className = 'remove_btn';
this.ui.remove_btn.appendChild(document.createTextNode('Выложить'));
c.appendChild(this.ui.remove_btn);
$(this.ui.remove_btn).bind('click',function () { this.controller.OnRemove(); });

this.UpdateUI();
}

this.Deploy = function ()
{
this.LoadConfig();

this.CreateUI(this.container);

this.cart.RegisterItemPanel(this.id,this);
}

this.IsPrimary = function ()
{
if (m = window.location.toString().match(/_o(\d+)\./))
{
return (m[1] == this.id);
}
}

this.LoadConfig = function ()
{
this.id = $(this.container).attr('data-item-id');
this.price = $(this.container).attr('data-item-price');
this.max = $(this.container).attr('data-item-max');
}

this.OnAdd = function ()
{
this.Set(1);
}

this.OnCheckout = function ()
{
this.cart.Checkout();
}

this.OnSetAmount = function ()
{
var in_cart = this.cart.profile.items[this.id] || 0;
var new_amount = window.prompt('Количество:',in_cart);
if (new_amount != null)
{
this.Set(new_amount);
}
}

this.OnRemove = function ()
{
this.Set(0);
}

this.Set = function (new_amount)
{
this.cart.Set(this.id,new_amount);
}

this.Update = function ()
{
this.UpdateUI();
}

this.UpdateUI = function ()
{
var in_cart = this.cart.profile.items[this.id] || 0;
var is_added = (in_cart > 0);

$(this.ui.add_btn).toggle(!is_added);
$(this.ui.amount_input).toggle(is_added);
$(this.ui.checkout_btn).toggle((is_added && this.IsPrimary())?true:false);
$(this.ui.remove_btn).toggle(is_added);

this.ui.amount_input.innerHTML = 'В корзине: '+in_cart;
}

this.__construct(container);
}

function Tooltips (tags)
{
this.__construct = function (tags)
{
//this.tag = tag;

for (var i=0; i<tags.length; i++)
{
this.Deploy(tags[i]);
}
}

this.Deploy = function (tag)
{//alert('DDD');
var anchors = document.getElementsByTagName(tag);
for (var i=0; i<anchors.length; i++)
{//alert(anchors[i].hasAttribute);
if (anchors[i].getAttribute('title') != undefined)
{//alert('new_t');
anchors[i].tooltip = new Tooltip(anchors[i]);
}
}
}

this.__construct(tags);
}

function Tooltip (owner)
{
this.__construct = function (owner)
{
this.owner = owner;
this.Deploy();
}

this.Deploy = function ()
{
this.obj = document.createElement('div');
this.obj.className = 'tooltip';
this.content = this.owner.getAttribute('title');
if (this.content.search(/^\@/) == -1)
{
this.obj.className += ' text_tooltip';
}
$(this.owner); // IE
this.owner.parentNode.insertBefore(this.obj,this.owner);
this.owner.removeAttribute('title');
this.owner.on('mouseover',function (e) { obj = (e != undefined) ? e.target : event.srcElement; while (obj.parentNode && !obj.tooltip) {obj = obj.parentNode} obj.tooltip.Show(); if (e) e.preventDefault(); });
this.owner.on('mousemove',function (e) { obj = (e != undefined) ? e.target : event.srcElement; while (obj.parentNode && !obj.tooltip) {obj = obj.parentNode} obj.tooltip.Move(e); if (e) e.preventDefault(); });
this.owner.on('mouseout',function (e) { obj = (e != undefined) ? e.target : event.srcElement; while (obj.parentNode && !obj.tooltip) {obj = obj.parentNode} obj.tooltip.Hide(); if (e) e.preventDefault(); });
}

this.Load = function (uri)
{
this.api = new DataSource('raw',uri,new Callback(this,'LoadReply'));
this.api.Get();
}

this.LoadReply = function (data)
{
this.content = data;
this.obj.innerHTML = this.content;
}

this.Show = function ()
{
if (this.content)
{
if (this.content.search(/^\@/) != -1)
{
this.Load(this.content.replace(/^\@/,''));
this.content = '';
}
else if (this.content.search(/^\:/) != -1)
{
this.obj.innerHTML = decodeURIComponent(this.content.substr(1));
this.content = '';
}
else
{
this.obj.innerHTML = this.content; //this.obj.appendChild(document.createTextNode(this.content));
this.content = '';
}
}
this.obj.style.display = 'block';
this.Move();
}

this.Move = function (e)
{
var e = e || window.event || {};

var cursor_space = 10;

var screen_w = window.innerWidth || document.body.offsetWidth;//document.body.offsetWidth;
var screen_h = window.innerHeight || document.body.offsetHeight;//document.body.offsetHeight;

var object_w = this.obj.offsetWidth;
var object_h = this.obj.offsetHeight;

var screen_x = e.clientX;
var screen_y = e.clientY;

var doc_x = e.pageX ? e.pageX : e.clientX + document.body.scrollLeft; 
var doc_y = e.pageY ? e.pageY : e.clientY + document.body.scrollTop;
//alert(screen_w+','+object_w);
//alert('screen_y='+screen_y+'; object_h='+object_h+'; screen_h='+screen_h);
var top = (screen_y+object_h <= screen_h) ? doc_y+cursor_space : doc_y-(object_h-(screen_h-screen_y)); //doc_y+cursor_space : doc_y-object_h-cursor_space;
var left = (screen_x+object_w <= screen_w) ? doc_x+cursor_space : doc_x-object_w-cursor_space;
//alert(top+','+left);
this.obj.style.left = left+'px';
this.obj.style.top = top+'px';
}

this.Hide = function ()
{
this.obj.style.display = 'none';
}

this.__construct(owner);
}function Includes (css, key) // include_box, 191
{
this.__construct = function (css, key)
{
this.css = css;
this.key = key;

if (navigator.userAgent.search(/MSIE/) == -1)
{
this.Deploy();
}
}

this.Deploy = function ()
{
document.body.includes = this;
document.body.on('keydown',function (e) { this.includes.OnKeyDown(e); });
document.body.on('keyup',function (e) { this.includes.OnKeyUp(e); });
}

this.Hide = function ()
{
var divs = document.getElementsByTagName('div');
for (var i=0; i<divs.length; i++)
{
if (divs[i].className == this.css+'_active')
{
divs[i].className = this.css;
}
}
}

this.OnKeyDown = function (e)
{
if (e.which == this.key)
{
this.Show();
}
}

this.OnKeyUp = function (e)
{
if (e.which == this.key)
{
this.Hide();
}
}

this.Show = function ()
{
var divs = document.getElementsByTagName('div');
for (var i=0; i<divs.length; i++)
{
if (divs[i].className == this.css)
{
divs[i].className = this.css+'_active';
}
}
}

this.__construct(css, key);
}
var CLR=new Object();CLR.version=1442;CLR.AddEvent=function(obj,event,handler){tmp='__tmp';obj[event]=function(e){if(!e){e=window.event;}if(!e.target){e.target=e.srcElement;}obj[tmp]=handler;result=obj[tmp](e);obj[tmp]=null;return result;}};CLR.AddStrictEvent=function(obj,event,handler){tmp='__tmp';obj[event]=function(e){if(!e){e=window.event;}if(!e.target){e.target=e.srcElement;}obj[tmp]=handler;result=obj[tmp](e);obj[tmp]=null;e.cancelBubble=true;if(e.stopPropagation){e.stopPropagation();}return result;}};CLR.Append=function(baseVar,newValue){return newValue?newValue:baseVar;};CLR.ArrayToQuery=function(arr){var data='';for(var key in arr){data+='&'+key+'='+encodeURIComponent(arr[key]);}return data.substr(1);};CLR.FormatNumber=function(num,decNum,decSep,thSep){base=String(Math.ceil(num));fbase='';for(j=base.length;j>=0;j--){if((j<base.length-3)&&((base.length-j-1)%3==0)){fbase=thSep+fbase;}fbase=base.substr(j,1)+fbase;}base=fbase;tmp=String(Math.round(num*Math.pow(10,decNum)));decimals=tmp.substr(tmp.length-decNum,decNum);return base+decSep+decimals;};CLR.GetObject=function(id){return document.getElementById(id);};CLR.GetParentNode=function(name,node){while(node&&node.tagName.toLowerCase()!=name){node=node.parentNode;}return node;};CLR.GetClass=function(node){return(cname=node.getAttribute('class'))?cname:node.getAttribute('className');};CLR.GetCSSValue=function(element,property){if(element.currentStyle){return element.currentStyle[property];}else if(window.getComputedStyle){return document.defaultView.getComputedStyle(element,null).getPropertyValue(property);}};CLR.GetOffsetLeft=function(){return document.documentElement.scrollLeft?document.documentElement.scrollLeft:document.body.scrollLeft;};CLR.GetOffsetTop=function(){return document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop;};CLR.GetPixelLeft=function(obj){var curleft=0;if(obj.offsetParent){while(obj.offsetParent){curleft+=obj.offsetLeft;obj=obj.offsetParent;}}else if(obj.x){curleft+=obj.x;}return curleft;};CLR.GetPixelTop=function(obj){var curtop=0;if(obj.offsetParent){while(obj.offsetParent){curtop+=obj.offsetTop;obj=obj.offsetParent;}}else if(obj.y){curtop+=obj.y;}return curtop;};CLR.GetScreenHeight=function(){if(document.body.clientHeight){if(document.documentElement.clientHeight&&(document.documentElement.clientHeight<document.body.clientHeight)){return document.documentElement.clientHeight;}return document.body.clientHeight;}else if(document.documentElement.clientHeight){return document.documentElement.clientHeight;}};CLR.GetScreenWidth=function(){if(document.body.clientWidth){if(document.documentElement.clientWidth&&(document.documentElement.clientWidth<document.body.clientWidth)){return document.documentElement.clientWidth;}return document.body.clientWidth;}else if(document.documentElement.clientWidth){return document.documentElement.clientWidth;}};CLR.GetURL=function(uri){url=document.location.protocol+'/'+'/'+document.location.hostname;if(uri.substr(0,1)=='/'){url+=uri;}else{url+=document.location.pathname.replace(/\/[^\/]+$/,'/')+uri;}return url;};CLR.GetUserAgentInfo=function(){if(window.userAgentInfo){return window.userAgentInfo;}var userAgent=navigator.userAgent;var userAgentName=navigator.appName;var userAgentVersion=navigator.appVersion;var info=new Object();var matches;if(userAgentName.search(/Microsoft\sInternet\sExplorer/i)!=-1){info.engine='MSIE';info.name='Internet Explorer';matches=userAgentVersion.match(/(\d\.\d)/);if(matches&&matches[1].length>0){info.version=matches[1];}else{info.version=false;}}else if(userAgent.search(/Firefox/i)!=-1){info.engine='Gecko';info.name='Firefox';matches=userAgentVersion.match(/Firefox\/(\d\.\d)/);if(matches&&matches[1].length>0){info.version=matches[1];}else{info.version=false;}}else if(userAgent.search(/Mozilla/i)!=-1){info.engine='Gecko';info.name='Mozilla';matches=userAgentVersion.match(/(\d\.\d)/);if(matches&&matches[1].length>0){info.version=matches[1];}else{info.version=false;}}else if(userAgentName.search(/Opera/i)!=-1){info.engine='Opera';info.name='Opera';matches=userAgentVersion.match(/(\d\.\d)/);if(matches&&matches[1].length>0){info.version=matches[1];}else{info.version=false;}}else{info.engine=false;info.name=false;info.version=false;}window.userAgentInfo=info;return info;};CLR.ProcessTemplate=function(template,values){for(var key in values){template=template.replace(new RegExp('\{'+key+'\}'),values[key]);}return template;};CLR.RandomNumber=function(min,max){return Math.round(min+(max-min)*Math.random());};CLR.RandomString=function(len){matrix='0123456789abcdefghijklmnopqrstuvwxyz';str='';for(i=1;i<=len;i++){str+=matrix.substr(CLR.RandomNumber(0,matrix.length-1),1);};return str;};CLR.ReplaceNodeContents=function(dstNode,srcNode){var i,nodes,node;nodes=dstNode.childNodes;for(i=nodes.length-1;i>=0;i--){dstNode.removeChild(nodes[i]);}nodes=srcNode.childNodes;for(i=0;i<nodes.length;i++){dstNode.appendChild(nodes[i].cloneNode(true));}};CLR.RxGet=function(str,rx,i){if(m=str.match(rx)){return m[i];}};CLR.RxQuote=function(str){};CLR.SetClass=function(node,value){node.setAttribute((navigator.appName.search(/Microsoft\sInternet\sExplorer/i)!=-1)?'className':'class',value);};// eShop - Kernel - Created by RaZEr in 2003 .

function str_replace(str_fr,str_to,str_dest) {
while ((pos = str_dest.indexOf(str_fr))>0) str_dest = str_dest.substr(0,pos)+str_to+str_dest.substr(pos+1);
return str_dest;
}

function DTF_GetDaysInMonth (year,month) {
thisDate = new Date(year,month,0);
return thisDate.getDate();
}

function DTF_FormatNumber (number) {
str = number.toString();
return (str.length < 2)?"0"+str:str;
}

function DTF_MakeTimestamp (milliseconds) {
curDate = new Date(milliseconds);
return curDate.getFullYear()+"-"+DTF_FormatNumber(curDate.getMonth()+1)+"-"+DTF_FormatNumber(curDate.getDate())+" "+
DTF_FormatNumber(curDate.getHours())+":"+DTF_FormatNumber(curDate.getMinutes())+":"+DTF_FormatNumber(curDate.getSeconds());
}

function FDI_Process (elemId,newValue) {
curDate = new Date();
document.getElementById(elemId).value = DTF_MakeTimestamp(curDate.getTime()+(newValue*1000));
}

function FDP_RefreshDaysCombo (selectElem,daysCount) {
if (selectElem.options.length < daysCount) {
for (i=selectElem.options.length-1;i<=daysCount;i++) selectElem.options[i] = new Option(i,i,false,false);
} else if (selectElem.options.length > daysCount) {
for (i=selectElem.options.length-1;i>daysCount;i--) {
if (selectElem.options[i].selected) selectElem.options[i-1].selected = true;
selectElem.options[i] = null;
}
}
}

function FDP_Refresh (elemName,sender)
{
fr_day = document.getElementById(elemName+"_fr_day");
fr_month = document.getElementById(elemName+"_fr_month");
fr_year = document.getElementById(elemName+"_fr_year");
fr_date = new Date(fr_year.value,fr_month.value-1,fr_day.value);

to_day = document.getElementById(elemName+"_to_day");
to_month = document.getElementById(elemName+"_to_month");
to_year = document.getElementById(elemName+"_to_year");
to_date = new Date(to_year.value,to_month.value-1,to_day.value);

//alert(fr_date+'--'+to_date);

if (to_date.getTime()-fr_date.getTime() < 86400000)
{
if (sender == 0)
{
// init
to_date = new Date();
fr_date = new Date(to_date.getTime()-86400000*30);
}
else
{
fr_date = new Date(to_date.getTime()-86400000);
to_date = new Date(fr_date.getTime()+86400000);
}
if ((sender == 1) || (sender == 0))
{
// from left
to_day.value = DTF_FormatNumber(to_date.getDate());
to_month.value = DTF_FormatNumber(to_date.getMonth()+1);
to_year.value = to_date.getFullYear();
}
if ((sender == 2) || (sender == 0))
{
// from right
fr_day.value = DTF_FormatNumber(fr_date.getDate());
fr_month.value = DTF_FormatNumber(fr_date.getMonth()+1);
fr_year.value = fr_date.getFullYear();
}
}
FDP_RefreshDaysCombo(fr_day,DTF_GetDaysInMonth(fr_year.value,fr_month.value));
FDP_RefreshDaysCombo(to_day,DTF_GetDaysInMonth(to_year.value,to_month.value));
}


function UseTool (url, target, width, height)
{
toolWin = window.open(url,'toolwin','width='+width+',height='+height+
',resizable=no,scrollbars=no,menubar=no,toolbar=no,location=no,status=no');
toolWin.SubmitValue = function (value)
{
var targetObj = document.getElementById(target);
if (targetObj && targetObj.value !== undefined)
{
targetObj.value = value;
}
};
}



Dates = new Object();
Dates.GetDaysInMonth = function (date)
{
return (new Date(date.getFullYear(),date.getMonth()+1,0)).getDate();
};



Events = new Object();
Events.AddHandler = function (object, event, handler)
{
if (object.addEventListener)
{
object.addEventListener(event,handler,false);
}
else
{
eval('object.on'+event+' = handler;');
}
};



Strings = new Object();

Strings.NameToLogin = function (str)
{
var func = function (c)
{
var from = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя!@$ ';
var to1x = 'abvgdee0ziyklmnoprstufhc123#i#e45ias_';
var to2x = 'zhchshshyuya';
var index = from.indexOf(c);
if (index != -1)
{
var repl = to1x.substr(index,1);
if (repl != '#')
{
var m = repl.match(/^\d$/); //alert(m);
return !m ? to1x.substr(index,1) : to2x.substr(m*2,2);
}
else
{
return '';
}
}
else
{
return '';
}
}; 
return str.replace(/[^a-z0-9_\-]/gi,func);
};

Strings.Repeat = function (str, count)
{
var out = '';
for (var i=0; i < count; i++)
{
out += str;
}
return out;
};



function FormDate (name, value, isOptional)
{ 
this.name = name;
this.value = value;
this.isOptional = isOptional;
this.date = new Date(value ? value*1000 : (new Date()).getTime());
this.prefix = 'date'+Math.round(Math.random()*1000);
this.months = new Array('Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь');

this.BuildUI = function ()
{
// Base
var out = '';

if (this.isOptional)
{
out += '<input type="checkbox" id="'+this.GetName('switch')+'" '+(this.value ? 'checked ' : '')+'/>';
}

out += '<input type="hidden" id="'+this.GetName('date')+'" name="'+this.name+'" value="'+this.value+'" />';

out += '<span id="'+this.GetName('box')+'">';

// Days
var days = Dates.GetDaysInMonth(this.date);
out += '<select id="'+this.GetName('day')+'" value="">';
for (var i=1; i<=days; i++)
{
out += '<option value="'+i+'">'+i+'</option>';
}
out += '</select>';

// Months
out += '<select id="'+this.GetName('month')+'" value="">';
for (var i=0; i<=11; i++)
{
out += '<option value="'+i+'">'+this.FormatNumber(i+1,2)+' - '+this.months[i]+'</option>';
}
out += '</select>';

// Years
var from = this.date.getFullYear()-5;
var to = (new Date()).getFullYear()+5;
out += '<select id="'+this.GetName('year')+'" value="">';
for (var i=from; i<=to; i++)
{
out += '<option value="'+i+'">'+i+'</option>';
}
out += '</select>';

out += '</span>';

document.write(out);

// Tune
var dayObj = this.GetUI('day');
var monthObj = this.GetUI('month');
var yearObj = this.GetUI('year');

dayObj.value = this.date.getDate();
monthObj.value = this.date.getMonth();
yearObj.value = this.date.getFullYear();

var self = this;
dayObj.onchange = function () { self.SetDay(this.value); }
monthObj.onchange = function () { self.SetMonth(this.value); }
yearObj.onchange = function () { self.SetYear(this.value); }

if (this.isOptional)
{
var switchObj = this.GetUI('switch');
switchObj.onclick = function () { self.SetState(); }
switchObj.onchange = function () { self.SetState(); }
this.SetState();
}
};

this.ClearValue = function ()
{
this.GetUI('date').value = '0';
};

this.FormatNumber = function (num, len)
{
var str = num.toString();
return (str.length < len) ? Strings.Repeat('0',len-str.length)+str : str;
};

this.GetUI = function (name)
{
return document.getElementById(this.GetName(name));
};

this.GetDate = function ()
{
return Math.round(this.date.getTime()/1000);
};

this.GetName = function (name)
{
return this.prefix+name;
};

this.SetValue = function ()
{
this.GetUI('date').value = this.GetDate();
};

this.SetDay = function (day)
{
this.date.setDate(day);
this.SetValue();
};

this.SetMonth = function (month)
{
this.date.setMonth(month);
if (this.date.getMonth() != month)
{
this.SetMonth(month); // unclean method
}
this.UpdateUI();
this.SetValue();
};

this.SetYear = function (year)
{
this.date.setFullYear(year);
this.UpdateUI(); // update days count (feb 28)
this.SetValue();
};

this.SetState = function ()
{
checkbox = this.GetUI('switch');
groupbox = this.GetUI('box');
if (checkbox.checked)
{
groupbox.style.visibility = 'visible';
this.SetValue();
}
else
{
groupbox.style.visibility = 'hidden';
this.ClearValue();
}
}

this.UpdateUI = function ()
{
var ui = this.GetUI('day');
var srcDays = ui.options.length;
var dstDays = Dates.GetDaysInMonth(this.date);
//alert('UI: '+srcDays+'->'+dstDays);
if (dstDays > srcDays)
{
// add
for (var i=srcDays+1; i <= dstDays; i++)
{
ui.options[i-1] = new Option(i,i,false,false);
}
}
else if (dstDays < srcDays)
{
// remove
for (var i=srcDays; i >= dstDays+1; i--)
{
if (ui.options[i-1].selected)
{
ui.options[i-2].selected = true;
}
ui.options[i-1] = null;
}
}
};

this.BuildUI();
}



function FormPassword (name, value)
{
this.name = name;
this.value = value;

this.prefix = 'date'+Math.round(Math.random()*1000);

this.colors = new Array('#FFFFFF','#FF0000','#FF8A00','#FFD100','#BACF00','#40BF00');
this.ranges = {
'LettersEnSmall': 'abcdefghigklmnopqrstuvwxyz',
'LennersEnBig': 'ABCDEFGHIGKLMNOPQRSTUVWXYZ',
'LettersRuSmall': 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя',
'LettersRuBig': 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ',
'Digits': '0123456789'
};
this.sequences = {
'KeyboardEnSmall': 'qwertyuiopasdfghjklzxcvbnm',
'KeyboardEnBig': 'QWERTYUIOPASDFGHJKLZXCVBNM',
'KeyboardRuSmall': 'йцукенгшщзхъфывапролджэячсмитьбю',
'KeyboardRuBig': 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
};
this.stupid = '1234567890 admin anonimous cccp guest god host fsb kgb login none null password root swordfish zerocool';

this.BuildUI = function ()
{
var out = '<table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td>';
out += '<input type="text" id="'+this.GetName('Field')+'" name="'+this.name+'" value="'+this.value.replace(/\"/,'&quot;')+'" />';
out += '</td><td class="dark">&nbsp;качество:</td><td>';
out += '<div class="CntGauge"><div id="'+this.GetName('Progress')+'" class="Progress"></div></div>';
out += '</td></tr></tbody></table>';
document.write(out);

var self = this;
var field = this.GetObject('Field');
var handler = function (e) { return self.UpdateRank(); };
Events.AddHandler(field,'keyup',handler);
Events.AddHandler(field,'keypress',handler);
Events.AddHandler(field,'change',handler);

this.UpdateRank();
};

this.GetName = function (name)
{
return this.prefix+name;
};

this.GetObject = function (name)
{
return document.getElementById(this.prefix+name);
};

this.Rank = function (pass)
{
var inRanges = 0;
var inSequences = 0;
var inStupids = 0;
var symbols = 0;
var result = 0;

if (pass.length > 1)
{
// Ranges
for (var range in this.ranges)
{
if (pass.search(new RegExp('['+this.ranges[range]+']')) != -1)
{
inRanges++;
symbols += this.ranges[range].length;
}
}
if (pass.search(new RegExp('[^a-zа-я0-9]+','i')) != -1)
{
inRanges++;
symbols += 128; // approx: 256-59*2-10
}

if (inRanges == 1)
{
// Stupid
if (pass.search(new RegExp('^(.)\\1{'+(pass.length-1)+'}$')) == -1)
{
// Sequences
var inSequences = 0;
for (var sequence in this.sequences)
{
if (this.sequences[sequence].search(new RegExp(pass.replace(/[^\w]/,''))) != -1)
{
inSequences++;
}
}
}
else
{
inSequences = 1;
inStupids = 1;
}
}
if ((this.stupid.indexOf(pass) != -1) || (this.stupid.toUpperCase().indexOf(pass) != -1))
{
inStupids = 1;
}

// Analyze
var modifer = 1;
if (inSequences)
{
modifer -= 0.1; // <-- sequence effect
}
if (inStupids)
{
modifer -= 0.25; // <-- stupid effect
}
modifer += inRanges/2.8; // <-- range effect
modifer -= ((256/6)-(symbols/inRanges))*0.025; // <-- symbols effect

result = Math.ceil((pass.length/3.2)*modifer); // <-- length effect
}
else
{
result = 1;
}
//alert(result+' (mod: '+modifer+', ranges: '+inRanges+' seqs: '+inSequences+' stupids: '+inStupids);
return (result > 5) ? 5 : result;
//return result+' (mod: '+modifer+', ranges: '+inRanges+' seqs: '+inSequences+' stupids: '+inStupids;
};

this.UpdateRank = function ()
{
var rank = this.Rank(this.GetObject('Field').value);
var progress = this.GetObject('Progress');
progress.style.width = (rank*20)+'px';
progress.style.backgroundColor = this.colors[rank];
};

// Constructor
this.BuildUI();
}

function RefSpy ()
{
this.token = 'ref';
this.divider = '<D>';
this.localDomains = 'intimshop.ru,new.intimshop.ru,intim-shop.ru,sex-shop.ru,vibrator.ru';
this.expires = 30;

this.Launch = function ()
{
//alert('incoming: '+this.IsIncoming()+'; haverecord:'+this.HaveRecord());
if (this.IsIncoming() && !this.HaveRecord())
{
//alert('set record');
this.SetRecord();
}
};

this.IsIncoming = function ()
{
//alert('ref: '+document.referrer);
if (document.referrer)
{
var refSite = this.GetDomain(document.referrer);
//alert('refsite: '+refSite);
if (refSite.length)
{
//alert('in local?: '+this.localDomains.search(new RegExp('(^|\,)'+this.RxQuote(refSite)+'(\,|$)')));
return (this.localDomains.search(new RegExp('(^|\,)'+this.RxQuote(refSite)+'(\,|$)')) == -1);
}
}
};

this.GetDomain = function (url)
{
var m = url.match(/^\w+\:\/\/.*?(?:www\.)?((?:[a-z0-9\-]+\.)*[a-z]+)(?:\:\d+)?\//i);
return m ? m[1] : false;
};

this.HaveRecord = function ()
{
return this.GetCookie(this.token) ? true : false;
};

this.MakeRecord = function ()
{
var now = new Date();
return document.referrer+this.divider+Math.round(now.getTime()/1000);
};

this.SetRecord = function ()
{
this.SetCookie(this.token,this.MakeRecord(),this.expires);
};


this.GetCookie = function (name)
{
var m = document.cookie.match(new RegExp(name+'=([^;]+)'));
return m ? m[1] : null;
};


this.SetCookie = function (name, value, expires)
{
var str = name+'='+escape(value);
if (expires > 0)
{
var dateNow = new Date();
var dateExp = new Date(dateNow.getTime()+(expires*86400000));
str += ';expires='+dateExp.toUTCString();
}
//alert('cookie: '+str);
document.cookie = str;
};

this.RxQuote = function (str)
{
return str.replace(/[^\w]/g,"\\$&");
};

}
function BookmarkPanel (container, group, key, cfg)
{
this.__construct = function (container, group, key, cfg)
{
this.container = Z(container);
this.group = group;
this.key = key;
this.state = this.IsBookmarked();
this.cfg = cfg || {};
this.Deploy();
}

this.Deploy = function ()
{
this.gui = {};

this.container.className = 'bookmark_panel'+(this.cfg.css_class?' '+this.cfg.css_class:'');

this.gui.add_btn = document.createElement('a');
this.gui.add_btn.className = 'add_bookmark_btn';
this.gui.add_btn.controller = this;
this.gui.add_btn.setAttribute('href','javascript:void(0);');
this.gui.add_btn.appendChild(document.createTextNode(this.cfg.nolabels?'':'Отложить')); // \u00a0
this.container.appendChild(this.gui.add_btn);
this.gui.add_btn.on('click',function(){ this.controller.AddBookmark(); });

this.gui.remove_btn = document.createElement('a');
this.gui.remove_btn.className = 'remove_bookmark_btn';
this.gui.remove_btn.controller = this;
this.gui.remove_btn.setAttribute('href','javascript:void(0);');
this.gui.remove_btn.appendChild(document.createTextNode(this.cfg.nolabels?'':'Снять закладку'));
this.container.appendChild(this.gui.remove_btn);
this.gui.remove_btn.on('click',function(){ this.controller.RemoveBookmark(); });

this.gui.list_btn = document.createElement('a');
this.gui.list_btn.className = 'list_bookmarks_btn';
this.gui.list_btn.setAttribute('href',this.cfg.list_href);
this.gui.list_btn.appendChild(document.createTextNode(this.cfg.list_title));
this.container.appendChild(this.gui.list_btn);

this.UpdateGUI();
}

this.AddBookmark = function ()
{
this.UpdateBookmarkDB(1);
this.UpdateGUI();
}

this.GetBookmarksCount = function ()
{
var bookmarks = document.cookies.get(this.group);
return bookmarks.length ? bookmarks.split(',').length : 0;
}

this.IsBookmarked = function ()
{
bookmarks = document.cookies.get(this.group);
if (bookmarks.length)
{
bookmarks = bookmarks.split(',');
for (var i=0; i<bookmarks.length; i++)
{
if (bookmarks[i] == this.key)
{
return true;
break;
}
}
}
return false;
}

this.RemoveBookmark = function ()
{
this.UpdateBookmarkDB(0);
this.UpdateGUI();
}

this.StateCallback = function ()
{
if (this.cfg.state_callback)
{
if (!this.dx)
{
this.dx = new DataExchange();
}
this.dx.Get(this.cfg.state_callback+'&state='+this.state,new Callback(this,'StateCallbackReply'));
}
}

this.StateCallbackReply = function (data)
{
//this.UpdateGUI();
}

this.UpdateBookmarkDB = function (state)
{
bookmarks = document.cookies.get(this.group);
bookmarks = bookmarks.length ? bookmarks.split(',') : [];
for (var i=0; i<bookmarks.length; i++)
{
if (bookmarks[i] == this.key)
{
//delete bookmarks[i];
bookmarks.splice(i,1);
break;
}
}
if (state)
{
bookmarks.push(this.key);
}
bookmarks = bookmarks.join(',');
document.cookies.set(this.group,bookmarks,86400*365);
this.state = state;
this.StateCallback();
}

this.UpdateGUI = function ()
{
if (this.state)
{
this.gui.add_btn.style.display = 'none';
this.gui.remove_btn.style.display = '';
}
else
{
this.gui.add_btn.style.display = '';
this.gui.remove_btn.style.display = 'none';
}
if (this.cfg.list_href && (count = this.GetBookmarksCount()))
{
this.gui.list_btn.innerHTML = this.cfg.list_title+'('+count+')';
this.gui.list_btn.style.display = '';
}
else
{
this.gui.list_btn.style.display = 'none';
}
}

this.__construct(container, group, key, cfg);
}
