﻿/*************************************************
 *     Модуль манипуляции свойствами объекта     *
 *                                               *   
 *     Автор:                     Агроник А.Ю.   *
 *     Дата создания:             08.06.2007     *
 *     Дата изменения:            21.07.2008     * 
 *                                               *
 *                                               *
 *		Внимание! данный файл является           *
 *		частью программного продукта SCSC        *
 *      и не поставляется отдельно. Права        *
 *      на программный продукт SCSC              *
 *      принадлежат компании A2 www.a2soft.ru    *
 *											   	 *
 *************************************************/
		 
 var $global = {
    ShowText:"Подробнее",
    HideText:"Скрыть",
    Mouse:{
        X:"0",
        Y:"0"
    },
    GetConst:{
        Up:"up",
        First:"first",
        Last:"last",
        Next:"next",
        Previous:"prev"
    },
    /*
    BindEvent: function(obj, eventName)
    {
        var arrName = "_on" + eventName;
        var eventName = "On" + eventName;
        var addEvent = "AddOn" + eventName;
        // дописать removeEvent
        var removeEvent = "RemoveOn" + eventName;
        
        obj.arrName = [];
        obj.eventName = function(args)
        {
            for (var i in this.Obj.ArrName)
            {
                i(args);
            }
        }.bind({Obj:this, ArrName:arrName});
        obj.addEvent = function(funcToCall)
        {
            if (funcToCall)
                this.Obj.ArrName.push(funcToCall);
        }.bind({Obj:this, ArrName:arrName});
    },
    */
    MakeFlash:function(src, id, width, height, wmode, scale, quality)
    {
        var result = "<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0\" width=\""+width+"\" height=\""+height+"\" id=\""+id+"\" align=\"top\"><param name=\"allowScriptAccess\" value=\"always\" /><param name=\"movie\" value=\""+src+"\" /><param name=\"menu\" value=\"true\" /><param name=\"quality\" value=\""+quality+"\" /><param name=\"scale\" value=\""+scale+"\" /><param name=\"salign\" value=\"lt\" /><param name=\"wmode\" value=\""+wmode+"\" /><param name=\"devicefont\" value=\"true\" /><embed src=\""+src+"\" menu=\"true\" quality=\""+quality+"\" scale=\""+scale+"\" salign=\"lt\" wmode=\""+wmode+"\" devicefont=\"true\" bgcolor=\"#ffffff\" width=\""+width+"\" height=\""+height+"\" name=\""+id+"\" align=\"top\" allowScriptAccess=\"always\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" /></object>";
        return result;
    },    
    Extend: function(obj, eobj, prefix)
    {
		for(var _prop in eobj)
			obj[prefix+_prop] = eobj[_prop];
		return obj;	
    },
    ExtendPrivate: function(obj, eobj)
    {
		$G.Extend(obj, eobj, "_");
    },
    Clone: function(obj, nofuncs) // Попробовать
    {
        var a = new Object();
        for(var i in obj)
            if(!nofuncs || !$global.IsFunction(obj))        
                a[i] = obj[i];
        return a;
    },
    GetKeyCode:function(e)
    {
		var e = e ? e : window.event;
		var code = e.keyCode ? e.keyCode : e.which;
		return code;
    },
    Date:
    {
        Month: ["", "января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"],
        MonthEntity: ["", "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"],
        DaysOfWeek: ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"],
        DaysOfWeekShort: ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"],
        Decade: function(date)
        {
            return Number(date.getFullYear().toString().substr(0, 3)+"0");
        },
        Clone: function(date)
        {
            var _wd = new Date();
	        _wd.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
	        return _wd;
        },
        Compare: function(date1, date2)
        {
            return ((date1.getFullYear() == date2.getFullYear()) &
                    (date1.getMonth() == date2.getMonth()) &
                    (date1.getDate() == date2.getDate()));
        },
        Format: function(str)
        {
            return $global.FormatDate(str);
        },
        ShortDate:function(date)
        {
            return  $G.Number.Norm(date.getDate())+"."+$G.Number.Norm((date.getMonth()+1))+"."+date.getFullYear();
        },
        FormString: function(date)
        {
            return  date.getDate()+" "+$global.Date.Month[date.getMonth()+1]+" "+date.getFullYear();
        }
    },
    FormatDate: function(str)
    {
        var sep = str.indexOf(".") != -1 ? "." : "/";
        var m = sep == "." ? 1 : 0;
        var d = m == 1 ? 0 : 1;
        var date = str.split(sep);
        if($global.Date.Month[Number(date[m])] != null)
            date[m] = $global.Date.Month[Number(date[m])];
        var res = date[d] + " " +date[m]+ " "+date[2];
        if(res.indexOf(":") != -1)
            res = res.substring(0, res.lastIndexOf(":"));
        return res;
    },
    CurrentMenu:null, // Что Это ??!!
    SwapClasses:function(class1, class2, obj) // Переключить классы у объекта (1 -> 2, 2 -> 1)
    {
        if(obj)
        {
            obj.className = obj.className == class1 ? class2 : class1;
        }
    },
    SwapAttributeValues:function(value1, value2, obj, attr) // Переключить значения атрибутов ???
    {
        if(obj)
        {
            var attribute = obj.getAttributeNode(attr);
            if(attribute)
				attribute.value = attribute.value == value1 ? value2 : value1;
        }
    },
    SetAttr:function(obj, attr, value)
    {
		var _attr = obj.getAttributeNode(attr);
		if(_attr == null)
			_attr = document.createAttribute(attr);
		_attr.value = value;
		//alert(attr + " : "+value);
		obj.setAttributeNode(_attr);
    },
    SwapText:function(obj, Text1, Text2) // Переключить текст
    {
        if(obj)
        {
            var tmp = this.GetText(obj);
            this.SetText(obj, (tmp == Text1 ? Text2 : Text1));
        }
    },
    SwapVisibility:function(obj) // Переключить выдимость элемента
    {
        this.Display.Swap(obj, "none", "block");
    },
    Cookie:
    {
		Set:function(name, value, days, path, domain, secure) // установить заничение Cookie 
		{
			var expire = new Date();
			if(days)
				expire.setTime(expire.getTime() + (days*24*60*60*1000));
			document.cookie = name + "=" + escape(value) +
					((days) ? "; expires=" + expire.toGMTString() : "") +
					((path) ? "; path=" + path : "") +
					((domain) ? "; domain=" + domain : "") +
					((secure) ? "; secure" : "");
		},
		Get:function(name) // получить значение Cookie по имени
		{
			var cookie = " " + document.cookie;
			var search = " " + name + "=";
			var setStr = null;
			var offset = 0;
			var end = 0;
			if (cookie.length > 0) {
				offset = cookie.indexOf(search);
				if (offset != -1) {
					offset += search.length;
					end = cookie.indexOf(";", offset)
					if (end == -1) {
						end = cookie.length;
					}
					setStr = unescape(cookie.substring(offset, end));
				}
			}
			return(setStr);
		}
    },
    Display:{
        Swap:function(obj, value1, value2) // Переключить значение стиля display
        {
            if(obj)
            {
                obj.style.display = obj.style.display == value1 ? value2 : value1;
            }
        },
        Clear:function(obj)	// очистить значение стиля display
        {
            if(obj)
            {
                var _obj = obj;
                
                if(window["A2"])
                    if(A2.UI.Control.prototype.isPrototypeOf(obj))
                        _obj = obj.Holder;
                _obj.style.display = "";
            }
        },
        Block:function(obj)	// установить значение display в block
        {
            if(obj)
            {
                var _obj = obj;
                
                if(window["A2"])
                    if(A2.UI.Control.prototype.isPrototypeOf(obj))
                        _obj = obj.Holder;
                _obj.style.display = "block";
            }
        },
        Inline:function(obj) // установить значение display в inline
        {
            if(obj)
            {
                var _obj = obj;
                
                if(window["A2"])
                    if(A2.UI.Control.prototype.isPrototypeOf(obj))
                        _obj = obj.Holder;
                _obj.style.display = "inline";
            }
        },
        Hide:function(obj)	// установить значение display в none
        {
            if(obj)
            {
                var _obj = obj;
                
                if(window["A2"])
                    if(A2.UI.Control.prototype.isPrototypeOf(obj))
                        _obj = obj.Holder;
                _obj.style.display = "none";
            }
        },
        Visible:function(obj)
        {
            return obj.style.display != "none";
        },
        Blink:function(obj, values)
        {
            for(var i=0;i<values.length;i++)
            {
                obj.style.display = values[i];
            }
        }
    },
    GetParent:function(obj, depth) // получит родительский нод вверх на depth элементов
    {
        var res = null;
        if(obj)
        {        
            res = obj;
            var i = 1;
            while(depth >= i)
            {
                res = res.parentNode != null ? res.parentNode : res;
                i++;
            }
        }
        return res;
    },
    GetText:function(obj) //???
    {
        var result = "";
        if(obj)
            result = (obj.innerText) ? obj.innerText : ((obj.textContent) ? obj.textContent : "");
        return result;
    },
    SetText:function(obj, text)	// Безполезно, Использовать: obj.innerHTML = text; ???
    {
        if(obj)
        {
            if(obj.firstChild)
            {
                obj.removeChild(obj.firstChild);
            }
            
            obj.appendChild(document.createTextNode(text));
        }
    },
    SetError:function(obj)   // частная задача для проекта Tezey - ??? 
    {
        if(obj)
            obj.className = "Error";
    },
    ClearError:function(obj)   // частная задача для проекта Tezey - ??? 
    {
        if(obj)
            obj.className = "";
    },
    StepToNumber:function(str) // преобразует строку вида xkym к виду x000y000000
    {
        return str.replace(/k/gi, "000").replace(/m/gi, "000000");
    },
    NormalizeToNumber:function(obj)	// частная задача для проекта Tezey - ???
    {
        if(obj)
        {
            obj.value = Validator.NormalizeToNumber(obj.value);
            $global.ClearError(obj);
        }
    },    
    NormalizeToUpper:function(obj, border)  // частная задача для проекта Tezey - ???
    {
        if(obj)
        {
            obj.value = Validator.NormalizeToUpper(obj.value, border);
            $global.ClearError(obj);
        }
    },
    NormalizeToBottom:function(obj, border)  // частная задача для проекта Tezey - ???
    {
        if(obj)
        {
            obj.value = Validator.NormalizeToBottom(obj.value, border);
            $global.ClearError(obj);
        }
    },
    NormalizeByInterval:function(obj, up, down)  // частная задача для проекта Tezey - ???
    {
        if(obj)
        {
            obj.value = Validator.NormalizeByInterval(obj.value, up, down);
            $global.ClearError(obj);
        }
    },
    FindPosition:function(obj) 
    {
	    var curleft = curtop = 0;
	    if (obj.offsetParent) {
		    curleft = obj.offsetLeft
		    curtop = obj.offsetTop
		    while (obj = obj.offsetParent) {
			    curleft += obj.offsetLeft
			    curtop += obj.offsetTop
		    }
	    }
	    return [curleft,curtop];
    },
    GetTopLeft:function(obj)
    {
		var b = this.FindPosition(obj);
		return { x:b[0], y:b[1] };
    },
    /* Следующий блок заменить на что-нибудь типа:
     Align.AtCursor(), Align.ScreenCenter(), Align.Under(), Align.On(), Align.LeftOf(), Align.RightOf() */
    ShowAtPosition:function(obj, noshow, ox, oy)
    {
        if(obj)
        {
            obj.style.position = "absolute";
            obj.style.display = "block";
            obj.style.top = "0px";
            obj.style.left = "0px";
            var pos = $global.FindPosition(obj);
            obj.style.top = Number($global.Mouse.Y-pos[1]+(oy ? oy : 0))+"px";
            obj.style.left = Number($global.Mouse.X-pos[0]+(ox ? ox : 0))+"px";                
            
        }
    },
    ShowInPageCenterByBounds:function(obj, w, h)
    {
        if(obj)
	    {
	        obj.style.position = "absolute";
		    var _deltaX = (w/2);
		    var _deltaY = (h/2);
		    var _centerW = (this.Window.Width()/2)+$global.Window.Scroll.Left();
		    var _centerH = (this.Window.Height()/2)+$global.Window.Scroll.Top();
		    obj.style.top = ((_centerH-_deltaY )> 0) ? (Math.floor(_centerH-_deltaY )+"px") : "0px";
		    obj.style.left = ((_centerW-_deltaX )> 0) ? (Math.floor(_centerW-_deltaX )+"px") : "0px";
		    this.Display.Block(obj);		
	    }
    },
    ShowInPageCenter:function(obj)
    {
        if(obj)
	    {
			var w = obj.offsetWidth;
			var h = obj.offsetHeight;
			w = w == 0 ? this.GetStyle(obj, "width", true) : w;
			h = h == 0 ? this.GetStyle(obj, "height", true) : h;
			w += this.GetStyle(obj, "borderLeftWidth", true) + this.GetStyle(obj, "borderRightWidth", true);
			h += this.GetStyle(obj, "borderTopWidth", true) + this.GetStyle(obj, "borderBottomWidth", true);
			this.ShowInPageCenterByBounds(obj, w, h);
	    }
    },
    ShowUnderObject:function(obj, target, noabs)
    {
        if(obj && target)
        {
            obj.style.top = "0px";
            obj.style.left = "0px";                
            var oldPos = ($global.Browser.Detect.ie) ? [0,0] : $global.FindPosition(obj);
            var h = target.offsetHeight;
            var position = $global.FindPosition(target);
            if(!noabs){obj.style.position = "absolute";};
            obj.style.top = Number(position[1]+h+oldPos[1])+"px";
            obj.style.left = Number(position[0]+oldPos[0])+"px";
            if($global.Browser.Detect.opera)
            {
                obj.style.left = Number(position[0]+oldPos[0]-1)+"px";
            }
            obj.style.display = "block";
        }
    },
    ShowRightToObject:function(obj, target, noabs)
    {
        if(obj && target)
        {
            obj.style.top = "0px";
            obj.style.left = "0px";                
            var oldPos = ($global.Browser.Detect.ie && !$global.Browser.Detect.ie7) ? [0,0] : $global.FindPosition(obj);
            var w = target.offsetWidth;
            var position = $global.FindPosition(target);
            if(!noabs){obj.style.position = "absolute";};
            obj.style.top = Number(position[1]+oldPos[1])+"px";
            obj.style.left = Number(position[0]+w+oldPos[0])+"px";
//            if($global.Browser.Detect.opera)
//            {
//                obj.style.left = Number(position[0]+oldPos[0]-1)+"px";
//            }
            obj.style.display = "block";
        }
    },
    /* --- конец блока --- */
    TrackMousePosition:function(e) 
    {
	    var posx = 0;
	    var posy = 0;
	    if (!e) var e = window.event;
	    if (e.pageX || e.pageY) 	{
		    posx = e.pageX;
		    posy = e.pageY;
	    }
	    else if (e.clientX || e.clientY) 	{
		    posx = e.clientX + document.body.scrollLeft
			    + document.documentElement.scrollLeft;
		    posy = e.clientY + document.body.scrollTop
			    + document.documentElement.scrollTop;
	    }
	    $global.Mouse.X = posx;
	    $global.Mouse.Y = posy;
	},
	InitEvents:function(e)
	{
		var _o = document.onmousemove;
	    document.onmousemove = function(ev)
	    {
			if(_o)
				_o(ev);
			$global.TrackMousePosition(ev); 
		};	    
		this.Browser.Detect = this.Browser._detect();
	},
	Event:
	{
		Add:function( obj, type, fn ) 
		{
		    if(window["A2"])
			    if(UIControl.prototype.isPrototypeOf(obj))
				    return obj.AddEvent.bind(obj)(type, fn);
				
			var _obj = obj;
			if ( _obj.attachEvent ) 
			{
				_obj['e'+type+fn] = fn;
				_obj[type+fn] = function(){_obj['e'+type+fn]( window.event );}
				_obj.attachEvent( 'on'+type, _obj[type+fn] );
			} 
			else
				_obj.addEventListener( type, fn, false );
		    return _obj;
		},
		Remove:function( obj, type, fn ) 
		{
			var _obj = window["A2"] ? UIControl.prototype.isPrototypeOf(obj) ? obj.Holder : obj : obj;
			if ( _obj.detachEvent ) 
			{
				_obj.detachEvent( 'on'+type, _obj[type+fn] );
				_obj[type+fn] = null;
			} 
			else
				_obj.removeEventListener( type, fn, false );
		    return _obj;
		},
		KeyCode:function(e)
		{
		    return $global.GetKeyCode(e);
		},
		Target: function(e)
		{
		    var e = e ? e : event;
		    return e.target ? e.target : e.srcElement;
		}
	},
	Merge:function(func, func2)
	{
	    return function()
	    {
	        if(func)
	            func.apply(this, arguments);
	        if(func2)
	            func2.apply(this, arguments);
	    }
	},
	SwitchToggleGroupByClass:function(obj, class1, class2, formal) // Частная задача для Tezey - ?
	{
	    if(obj)
	    {
	        var objs = obj.parentNode.getElementsByTagName("div");
	        for(var i = 0;i<objs.length;i++)
	            if(objs[i] != obj)
	                if(objs[i].className.indexOf(formal) != -1)
	                    objs[i].className = class1[i];	               
	        obj.className = class2;
	    }
	},
	SwitchDivGroupClass:function(obj, toggleClass) // Частная задача для Tezey - ?
	{
	    if(obj)
	    {
	        var divGroup = obj.parentNode.getElementsByTagName("div");
	        for(var i = 0; i < divGroup.length; i++)
	            if(divGroup[i] != obj)
	                if(divGroup[i].getAttribute('defaultClass') != null)
	                    divGroup[i].className = divGroup[i].getAttribute('defaultClass');	               
	        obj.className = toggleClass;
	    }
	},
	Next:function(obj, num)
	{
	    var result = null;
	    if(obj)
	    {
	        if(num == null)
	        {
	            result = obj.nextSibling;
	            if(result != null)	            
	                if(result.nodeType == 3)
	                    result = this.Next(result);
	        }
	        else
	        {
	            result = this.Next(obj);
	            for(var i=1;i<num;i++)
	                result = this.Next(result);
	        }
	    }
	    return result;
	},
	Previous:function(obj, num)
	{
	    var result = null;
	    if(obj)
	    {
	        if(num == null)
	        {
	            result = obj.previousSibling;
	            if(result != null)	            
	                if(result.nodeType == 3)
	                    result = this.Previous(result);
	         }
	         else
	         {
	            result = this.Previous(obj);
	            for(var i=1;i<num;i++)
	                result = this.Previous(result);
	         }
	    }
	    return result;
	},
	XML:
	{
		Parse:function(xml)
		{
			if (window.ActiveXObject)
			{
				var doc=new ActiveXObject("Microsoft.XMLDOM");
				doc.async="false";
				doc.loadXML(xml);
			}
			else
			{
				var parser=new DOMParser();
				var doc=parser.parseFromString(xml,"text/xml");
			}
			return doc.documentElement;
		}
	},
	GetAttribute:function(obj, attr)
	{
	    var result = "";
	    if(obj)
	    {
	        var a = obj.getAttribute(attr);
	        a = a ? a : obj[attr];
	        result = this.isString(a) ? a : "";
	    }
	    return result;
	},
	ValueInArray:function(array, value)
	{
	    var result = false;
	    if(array)
	    {
	        if(value)
	        {
	            for(var i=0;i<array.length;i++)
	            {
	                result = result || (array[i] == value);
	            }
	        }
	    }
	    return result;
	},
	HasKey:function(array, key)
	{
		return array[key] != null;
	},
	NormCssStr:function(cssPropStr) // Приводит строку к виду для JS, например  margin-left > marginLeft
    {
        var i, c, a = cssPropStr.split('-');
        var s = a[0];
        for (i=1; i<a.length; ++i) 
        {
            c = a[i].charAt(0);
            s += a[i].replace(c, c.toUpperCase());
        }
        return s;
    },
    ShrinkStr:function(str, chars, last, empty)
    {
		return str.length > chars ? str.substring(0, chars) + last : str.length == 0 ? empty : str;
    },
    SmartShrinkStr:function(str, chars, last, empty)
    {
        var i = chars;
        while(str.length > i  && (str.substring(i, i+1) != " ")){ i++; };
        return str.length > i ? str.substring(0,i)+last : str.length == 0 ? empty : str;
    },
	GetStyle:function(obj, css, i) // Получает значение стиля, если если i == true возвращает int
	{
        var s, v = 'undefined', dv = document.defaultView;
        if(dv && dv.getComputedStyle)
        {            
            s = dv.getComputedStyle(obj,'');
            if (s) v = s.getPropertyValue(css);
        }
        else if(obj.currentStyle) 
            v = obj.currentStyle[this.NormCssStr(css)];
        else return null;
        return i ? (parseInt(v) || 0) : v;
	},
	SetStyle:function(sProp, sVal) // Устанавливает значение стиля для нескольких объектов (через запятую после sVal)
    {
        var i, e;
        
        for (i = 2; i < arguments.length; ++i) 
        {
            e = arguments[i];
            
            if(window["A2"])
                e = e.Holder ? e.Holder : e;
            if (e.style) 
            {
                try { e.style[sProp] = sVal; }
                catch (err) { e.style[sProp] = ''; } // ???
            }
        }
    },
    IsString:function(value) 
    {
        return typeof(value) == 'string';
    },
    IsNumber:function(value)
    {
		return typeof(value) == 'number';
    },
    IsFunction: function(value)
    {
        return Function.prototype.isPrototypeOf(value);
    },
    isString: function(value) { return this.IsString(value); },
    FilterByValue: function(array, attr, value)
    {
        var res = new Array();
        if(Array.prototype.isPrototypeOf(array))
            for(var i=0;i<array.length;i++)
                if(array[i][attr] == value)
                    res.push(array[i]);
        return res;
    },
    HTML:
    {
        Encode:function(str)
        {
            return str.replace(/\</gi, "&lt;").replace(/\>/gi, "&gt;");
        },
        URLEncode:function(str)
        {
            var res = $global.HTML.Encode(str);
            return res.replace(/\&/gi, "[#amp]");
        },
        GETVars:function()
        {
            var url = document.location.toString();
            var vars = {__count:0};
            if(url.indexOf("#") != -1)
                url = url.substring(0, url.indexOf("#"));
            if(url.indexOf("?") != -1)
            {
                url = url.substring(url.indexOf("?")+1, url.length-1);
                var _vars = url.split("&");
                for(var i=0;i<_vars.length;i++)
                {
                    var _cv = _vars[i].split("=");
                    if(_cv.length > 1)
                    {
                        vars[_cv[0]] = _cv[1];
                        vars.__count++;
                    }
                }
            } 
            return vars;
        },
        Decode:function(str)
        {
            return str.replace(/\&lt\;/gi, "<").replace(/\&gt\;/gi, ">");
        },
        URLDecode:function(str)
        {
            var res = str.replace(/\[\#amp\]/gi, "&");
            return $global.HTML.Decode(res);
        },
        Trims:function(str)
        {
            return str.replace(/\r/gi, "").replace(/\n/gi, "<br />");
        },
        GetDomain:function(str)
        {
			var domain = str ? str.replace("http://", "") : "";
			domain = domain.replace("www.", "");
			return domain.indexOf("/") != -1 ? domain.substring(0, domain.indexOf("/")) : domain;
        },
        Unicode:function(lit)
        {
			var el = $global.Tag("div", null, null, lit);
			return el.innerHTML;
        },
        NumForm:function(str, male, num)
        {
            var res = str;
            var a = num-Math.floor(num/10);
            res += male ? (a >= 5 || a == 0) ? "ов" : a==1 ? "" : "а" : (a >= 5 || a == 0) ? "" : a==1 ? "a" : "ы";
            return res;
        },
        Typo:function(str) // Пока тест
        {
            var r = str;
            var patt1 = /\"[^\"]+\"/gi;
            
            var a = patt1.exec(r);
            while(a != null)
            {
               var s = "";
               for (var i = 0; i < a.length; i++) {
                  s = s + a[i];
               }
               var g = s.replace(/\"/gi, "");
               r = r.replace(s, "\&laquo\;"+g+"\&raquo\;");
               a = patt1.exec(r);
            } 
            r = r.replace(/\s\-\s/gi, " &mdash; ");
            r = r.replace(/\.\.\.\s/gi, "&hellip;"+" ");
            return r;
        }
    },
    SetOpacity:function(obj, val) // Устанавливает значение непрозрачности для разных браузеров
    {
		this.Opacity.Set(obj, val);                
    },
    ClearOpacity:function(obj)
    {
		this.Opacity.Clear(obj);
    },
    Opacity:
    {
		Set:function(obj, val)
		{
			if(obj)
			{
				if ($global.isString(obj.style.opacity)) 
					obj.style.opacity = val + '';
				else if ($global.isString(obj.style.filter)) 
					obj.style.filter = 'alpha(opacity=' + (100 * val) + ')';
				else if ($global.isString(obj.style.MozOpacity)) 
					obj.style.MozOpacity = val + '';
				else if ($global.isString(obj.style.KhtmlOpacity)) 
					obj.style.KhtmlOpacity = val + '';
			}
		},
		Clear:function(obj)
		{
			if(obj)
			{
				if ($global.isString(obj.style.opacity)) 
					obj.style.opacity = '';
				else if ($global.isString(obj.style.filter)) 
					obj.style.filter = '';
				else if ($global.isString(obj.style.MozOpacity)) 
					obj.style.MozOpacity = '';
				else if ($global.isString(obj.style.KhtmlOpacity)) 
					obj.style.KhtmlOpacity = '';
			}	
		},
		Get: function(obj)
		{
		    if(obj)
		    {
		        if ($global.isString(obj.style.opacity)) 
					return Number(obj.style.opacity)*100;
				else if ($global.isString(obj.style.filter)) 
				    return Number(obj.style.filter.replace("alpha(opacity=", "").replace(")", ""));
				else if ($global.isString(obj.style.MozOpacity)) 
				    return Number(obj.style.MozOpacity)*100;
				else if ($global.isString(obj.style.KhtmlOpacity)) 
					return Number(obj.style.KhtmlOpacity)*100;
		    }
		}
    },
    GetCharPosition: function(str, chr, pos, up)
    {
        if(!up)
        {
            for(var i=pos;i>=chr.length;i--)
                if(str.substring(i-chr.length, i) == chr)
                    return Number(i-chr.length);
            return -1;
        }
        else
        {
            for(var i=pos;i<str.length;i++)            
                if(str.substring(i, i+chr.length) == chr)
                    return i;
            return str.length;
        }
    },
    Selection:
    {
        Start:function(o)
        {
	        if (o.createTextRange) 
	        {

                o.focus();
                var r = document.selection.createRange();
                r.moveStart ('character', -o.value.length);
                return r.text.length;
                
	        } 
	        else 
	            return o.selectionStart
        },
        End: function(o) 
        {
	        if (o.createTextRange) 
	        {
	            o.focus();
		        var r = document.selection.createRange();
		        r.moveStart('character', -o.value.length);
		        return r.text.length;
	        } 
	        else 
	            return o.selectionEnd;
        },
        Set: function(o, start, end)
        {
            if(o.createTextRange)
            {
                var r = o.createTextRange();
                r.select();
                r.moveStart('character', start);
                r.moveEnd('character', -(r.text.length-end+start));
                r.select();
            }
            else
            {
                o.setSelectionRange(start, end);
            }
        }
    },
	GetElementsByAttribute:function(attribute, value)
	{
	    //TODO: Поиск элементов по значению атрибута... и нах, спрашивается???
	},
	GetClear:function()
	{
	    var clear = document.createElement("div");
	    clear.className = "clear";
	    return clear;
	},
	Window:
	{
	    _defaultWindowTitle: "",
	    _titleSpliter: " / ",
        SetTitle:function(texts)
	    {
	        document.title = this._defaultWindowTitle;
	        if($G.isString(texts))
	        {
	            if(texts)
	                document.title += this._titleSpliter+texts;  
	        }
	        else
	            for(var i=0;i<texts.length;i++)
	                document.title += this._titleSpliter+texts[i];
	    },
	    Size:function(axis)
        {
            var x,y;	
            if (self.innerHeight) 
            {
                 x = self.innerWidth;	    
                 y = self.innerHeight;	
            } 
            else if (document.documentElement && document.documentElement.clientHeight)
            {	
                 x = document.documentElement.clientWidth;	    
                 y = document.documentElement.clientHeight;	
            } 
            else if (document.body) 
            {
                 x = document.body.clientWidth;	    
                 y = document.body.clientHeight;	
            }
            return (axis == "x") ? x : (axis == "y") ? y : 0;
        },
	    Width:function()
	    {
	        return Validator.NormalizeToNumber(this.Size("x"));
	    },
	    Height:function()
	    {
	        return Validator.NormalizeToNumber(this.Size("y"));
	    },
	    Scroll:
	    {
			Left:function()
			{
				var res = 0;       
				if(document.documentElement)
					res = document.documentElement.scrollLeft;
				else
					res = document.body.scrollLeft;
			    if(res == 0)
			        return document.body.scrollLeft || 0;
			    else
			        return res;
			},
			Top:function()
			{
			    var res = 0;       
				if(document.documentElement)
					res = document.documentElement.scrollTop;
				else
					res = document.body.scrollTop;
			    if(res == 0)
			        return document.body.scrollTop || 0;
			    else
			        return res;
			}
	    }
	},
	IsChildOf:function(par, child, depth)
	{
	    if(child)
	    {
	        //alert(child);
	        var o = child.parentNode;
	        for(var i = 0;i<depth;i++)
	        {
	            if(o == null)
	                return false;
	            if(o == par)
	                return true;	            
	            o = o.parentNode;
	        }
	    }
	    return false;
	},
	ToolTip:
	{
	    Tip:null,
	    AlignType:
	    {
	        Center:"0",
	        Cursor:"1"
	    },
	    Align:"1",
	    Center:function()
	    {
	        this.Align = this.AlignType.Center;
	        return $global.ToolTip;
	    },
	    Cursor:function()
	    {
	        this.Align = this.AlignType.Cursor;
	        return $global.ToolTip;
	    },
	    Create:function()
	    {
	        if(this.Tip == null)
	        {
	            var items = $global.GetElementsByClass(document.body, "Global_ToolTip");
	            if(items.length == 0)
	            {
	                this.Tip = document.createElement("div");
	                this.Tip.className = "Global_ToolTip";
	                document.body.appendChild(this.Tip);
	                this.Tip.onclick = this.Close;
	            }
	            else
	                this.Tip = items[0];
	       }
	       return this.Tip;
	    },
	    Text:function(text, width)
	    {
	        var tip = this.Create();
	        if(tip)
	        {
	            tip.innerHTML = text;
	            if(width)
	            {
	                tip.style.width = width;
	            }
	            if(this.Align == this.AlignType.Cursor)
	                $global.ShowAtPosition(tip);
	            else if(this.Align == this.AlignType.Center)
	                $global.ShowInPageCenter(tip);
	        }
	    },
	    Object:function(obj, width)
	    {
	        var tip = this.Create();
	        if(tip)
	        {
	            tip.innerHTML = "";
	            if(obj)
	            {
	                tip.appendChild(obj);
	                if(width)
	                {
	                    tip.style.width = width;
	                }
	                if(this.Align == this.AlignType.Cursor)
	                    $global.ShowAtPosition(tip);
	                else if(this.Align == this.AlignType.Center)
	                    $global.ShowInPageCenter(tip);
	            }
	        }
	    },
	    Close:function()
	    {
	        var items = $global.GetElementsByClass(document.body, "Global_ToolTip");
	        if(items.length > 0)
	        {
	            items[0].style.width = "auto";
	            $global.Display.Hide(items[0]);
	        }
	    }
	},
	Number:
	{
		is2N:function(value)
		{
			return value/2 == Math.round(value/2);
		},
		toHex:function(value)
		{
		    return value.toString(16);
		},
		toDec:function(value)
		{
		    return parseInt(value, 16);
		},
		hexToColor:function(hex)
		{
		    return "#"+this.Norm(hex, 6);		   
		},
		decToColor:function(dec)
		{
		    return $global.Number.hexToColor($global.Number.toHex(dec));
		},
		colorToHex:function(color)
		{
		    return color.replace("#", "");
		},
		colorToDec:function(color)
		{
		    return $global.Number.toDec($global.Number.colorToHex(color));
		},
		toHexRGB:function(color)
		{
		    //alert(color.substr(1,2)+":"+color.substr(3,2)+":"+color.substr(5,2));
		    return {r:color.substr(1,2), g:color.substr(3,2), b:color.substr(5,2)};
		},
		toDecRGB:function(color)
		{
		    var _rbg = $global.Number.toHexRGB(color);
		    _rbg.r = $global.Number.toDec(_rbg.r);
		    _rbg.g = $global.Number.toDec(_rbg.g);
		    _rbg.b = $global.Number.toDec(_rbg.b);
		    return _rbg;
		},
		Norm:function(num, c)
		{
		    var a = num.toString();
		    var _c = c == null ? 2 : c;
		    while(a.length < _c)
		        a = "0"+a;
		    return a;
		}
	},
	Color:
	{
	    Plus:function(c1, c0)
	    {
	        var _c = {r:c1.r+c0.r, g:c1.g+c0.g, b:c1.b+c0.b};
	        return _c;
	    },
	    Minus:function(c1, c0)
	    {
	        var _c = {r:c1.r-c0.r, g:c1.g-c0.g, b:c1.b-c0.b};
	        return _c;
	    },
	    Mult:function(c1, c0)
	    {
	        var _c1 = c1;
	        if($global.IsNumber(c1))
	            _c1 = {r:_c1, g:_c1, b:_c1};
	        var _c0 = c0;
	        if($global.IsNumber(c0))
	            _c0 = {r:_c0, g:_c0, b:_c0};
	        return {r:Math.round(_c0.r*_c1.r), g:Math.round(_c0.g*_c1.g), b:Math.round(_c0.b*_c1.b)};    
	    },
	    fromRGB:function(rgb)
	    {
	        return "#"+$global.Number.Norm($global.Number.toHex(rgb.r))+$global.Number.Norm($global.Number.toHex(rgb.g))+$global.Number.Norm($global.Number.toHex(rgb.b));
	    }
	},
	Tag:function(tag, css, id, inner, other)
	{
		var element = document.createElement(tag);
		if(element)
		{
			if($global.IsString(css))
				element.className = css;
			if($global.IsString(id))
				element.id = id;
			if($global.IsString(inner))
				element.innerHTML = inner;
				
            var _other = other ? other 
                               : ( $global.IsString(css) == false && css != null) ? css 
                               : ( $global.IsString(id) == false && id != null ) ? id 
                               : ( $global.IsString(inner) == false && inner != null ) ? inner
                               : null;
            if(_other)
                $global.Extend(element, _other, "");
		}
		return element;
	},
	TagToString: function(tag)
	{
		return $G.Append($G.Tag("tst"), tag).parentNode.innerHTML;
	},
	AddText:function(to, text)
	{
		var _t = document.createTextNode(text);
		to.appendChild(_t);
		return to;
	},
	Append:function(to, what, anchor, before)
	{
	    var _to = to; 
	    var _what = what;
	    var _anchor = anchor;
	    if(window["A2"])
	    {
		    _to = A2.UI.Control.prototype.isPrototypeOf(to) ? to.Content : to; 
		    _what = A2.UI.Control.prototype.isPrototypeOf(what) ? what.Holder : what;
		    _anchor = A2.UI.Control.prototype.isPrototypeOf(anchor) ? anchor.Holder : anchor;
		}
		if(anchor)
		{
		    if(before)
		        _to.insertBefore(_what, _anchor);
		    else
		        if(_anchor.nextSibling)
		            _to.insertBefore(_what, _anchor.nextSibling)
		        else
		            _to.appendChild(_what);
		}
		else
		    _to.appendChild(_what);
		return what;
	},
	Get:
	{
		ById:function(id)
		{
			return document.getElementById(id);
		},
		ByTag:function(obj, tag, global)
		{
			return $global.GetElementsByTagName(obj, tag, global);
		},
		ByClass:function(obj, css)
		{
			return $global.GetElementsByClass(obj, css);
		}
	},
	GetElementsByTagName:function(obj, tag, global)
	{
	    var result = new Array();
	    if(obj != null)
	        if(tag != null)
	        {
	            for(var i=0;i<obj.childNodes.length;i++)
	            {
	                var _elem = obj.childNodes[i];
	                if(_elem.tagName)
	                {
	                    if(_elem.tagName.toLowerCase() == tag.toLowerCase())
	                    {
	                        result.push(_elem);
	                    }
	                    if(global)
                        {
                            var _tmp = $global.Get.ByTag(_elem, tag, true);
                            result = result.concat(_tmp);
                        }
	                }
	            }
	        }
	    return result;
	},
	RemoveEmptyNodes:function(array)
	{
	    var tmp = new Array();
	        for(var i=0;i<array.length;i++)
	            if(array[i].nodeType != 3)
	                tmp.push(array[i]);
	    return tmp;
	},
	GetElementByTagName:function(obj, tag, index)
	{
	    var result = null;
	    var array = $global.GetElementsByTagName(obj, tag);
	    if(array.length > 0)
	    {
	        var tmp = this.RemoveEmptyNodes(array);
	        if(index != null)
	        {
	            var ind = index == $global.GetConst.First ? 0 : index == $global.GetConst.Last ? (tmp.length-1) : Number(index);
	            if(ind < tmp.length)
	            {
	                result = tmp[ind];
	            } else { result = tmp[0]; }
	        } else { result = tmp[0]; }
	    }
	    return result;
	},
	GetElementsByClass:function(obj, className)
	{
	    var result = new Array();
	    if(obj)
	    {
	        if(obj.childNodes != null)
	        {
	            for(var i = 0;i<obj.childNodes.length;i++)
	            {
	                if(obj.childNodes[i] != null)	                
	                    if(obj.childNodes[i].className != null)
	                        if(obj.childNodes[i].className == className)
	                            result.push(obj.childNodes[i]);
	            }
	        }
	    }
	    return result;
	},
	GET:function(obj, path) // Получает элемент по строке вида "<param>:<value>,<param>:<value>" например "up:3,div:0"
	{
	    var result = obj;
	    var str = new String();
	    str = path;
	    if(obj)
	    {
	        var strArray = str.split(',');
	        for(var i = 0;i<strArray.length;i++)
	        {
	            var pair = strArray[i].split(':');
	            if(pair[0] == $global.GetConst.Up)
	                result = $global.GetParent(result, Number(pair[1]));
	            else if(pair[0] == $global.GetConst.Next)
	                result = $global.Next(result, Number(pair[1]));
	            else if(pair[0] == $global.GetConst.Previous)
	                result = $global.Previous(result, Number(pair[1]));
	            else
	            {
	                var _tag = pair[0];
	                if(_tag.substr(_tag.length-1, 1) == "s")
	                {
	                    result  = $global.GetElementsByTagName(result, _tag.substr(0, _tag.length-1));
	                    break;
	                }
	                else
	                    result = $global.GetElementByTagName(result, pair[0], pair[1]);
	            }
	        }
	    }
	    return result;
	},
	_browser: null,
	Browser:
	{
		Detect: new Object(),
		Manufacturer:function()
		{
			return $G._browser.firstChild.alt;		
		},
		_detect:function()
		{
			var BO = new Object(); 
			BO["ie"]        = false /*@cc_on || true @*/; 
			BO["ie4"]       = BO["ie"] && (document.getElementById == null); 
			BO["ie5"]       = BO["ie"] && (document.namespaces == null) && (!BO["ie4"]); 
			BO["ie6"]       = BO["ie"] && (document.implementation != null) && (document.implementation.hasFeature != null); 
			BO["ie55"]      = BO["ie"] && (document.namespaces != null) && (!BO["ie6"]); 
			BO["ie7"]       = navigator.userAgent.indexOf("IE 7") != -1;
			BO["ns4"]       = !BO["ie"] &&  (document.layers != null) &&  (window.confirm != null) && (document.createElement == null); 
			BO["opera"]     = (self.opera != null); 
			BO["gecko"]     = (document.getBoxObjectFor != null); 
			BO["khtml"]     = (navigator.vendor == "KDE"); 
			BO["konq"]      = ((navigator.vendor == 'KDE') || (document.childNodes) && (!document.all) && (!navigator.taintEnabled)); 
			BO["safari"]    = (document.childNodes) && (!document.all) && (!navigator.taintEnabled) && (!navigator.accentColorName); 
			BO["safari1.2"] = (parseInt(0).toFixed == null) && (BO["safari"] && (window.XMLHttpRequest != null)); 
			BO["safari2.0"] = (parseInt(0).toFixed != null) && BO["safari"] && !BO["safari1.2"]; 
			BO["safari1.1"] = BO["safari"] && !BO["safari1.2"] && !BO["safari2.0"]; 
			return BO; 
		}
	},
	Array:
	{
	    SortNumbersASC:function(a, b){ return a-b; },
	    SortNumbersDESC:function(a, b){ return b-a; },
	    Shuffle:function(a, b){ return (0.5-Math.random()); }
	}
} 

 var $G = $global;//Алиас для $global
 var _old = window.onload;
 window.onload = function()
 {
	if(_old)
		_old(); 
	$global.InitEvents(); 
};

Function.prototype.bind = function(obj) 
{
	var method = this,
	temp = function() 
	{
		return method.apply(obj, arguments);
	};
	return temp;
}
//String.prototype.trim = function()
//{
//    var str = this;
//    var a = str.length;
//    for(var i=str.length-1;i>0;i--)
//    {
//        a = i;
//        if(str.charAt(i) == " ")
//        {
//            
//        }
//    }
//}
Function.prototype.toNamespace = function(scope, name)
{
	scope[name] = this;
}
Array.prototype.contains = function(value)
{
	return $G.ValueInArray(this, value);
};
Array.prototype.remove = function(value)
{
	for(var i=0;i<this.length;i++)
		if(this[i] == value)
			this.splice(i,1);
}
Array.prototype.xjoin = function(sep, prop)
{
    var str = "";
    for(var i=0;i<this.length;i++)
    {
       var props = prop.split(".");
       var v = null;
       for(var j=0;j<props.length;j++)
       {
            if(v == null)
                v = this[i][props[j]];
            else
                v = v[props[j]];
            if(Function.prototype.isPrototypeOf(v))
                v = v();
            if(v == null)
                break;
       }
       if(v != null)
            str += v+((i==this.length-1) ? "" : sep);
    }
    return str;
}
Array.prototype.foreach = function(func)
{
    if(func)
    {
        for(var i=0;i<this.length;i++)
        {
            func(this[i], i);
        }
    }
}
Array.prototype.without = function(arr)
{
	var ret = new Array();
	var _arr = Array.prototype.isPrototypeOf(arr) ? arr : [arr];
	for(var i=0;i<this.length;i++)
		if(!_arr.contains(this[i]))
			ret.push(this[i]);
	return ret;
}
function rgb(r, g, b)
{
    return $G.Color.fromRGB({r:r, g:g, b:b});
}
