// текущий видимый элемент
g_current_visible = null;
// ширина клиентской области ( null, т.к. документ не загрузился)
g_all_width = null;
// высота клиентской области
g_all_height = null;
// полная высота документа
g_all_scroll = null;
// рут документа
g_root = document.URL.match( /(.*\/)[^\/]*$/)[1];
// эксплорер ли?
g_isIE = navigator.userAgent == "Microsoft Internet Explorer" ? true : false;
// массив скриптов документа
if ( !document.scripts) {
    document.scripts = document.getElementsByTagName('script');
}

function get_text( node) {
	temp = node.text || node.textContent;
	return temp || node.innerText || "";
}

function get_JSON( text) {
    if ( text) {
        return !(text.replace(/"(\\.|[^"\\])*"/g, '').match(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/)) &&
eval('(' + text + ')');
    } else {
        return false;    
    }    
}

function stripslashes( str ) {
	return str.replace('/\0/g', '0').replace('/\(.)/g', '$1');
}

// генерируем условия совпадения элемента для get_elements()
function get_expression( element, value, strictFlag) {
    if ( !value || !value.tagName) {
        return {
            exp: null,
            num: null
        }
    }
	// определяем, что надо искать
    regExp = /^\.([^\[]+)(?:\[(\d+)\])?/;
    regExp2 = /^(\w+)\.([^\[]+)(?:\[(\d+)\])?/;
    regExp3 = /^([^\[]+)(?:\[(\d+)\])?$/;
    // если необходимо найти точное совпадение
	if ( c_match = element.match( regExp) ) {
        if (strictFlag) {
            //:KLUDGE:
            c_regExp = new RegExp( "[^a-z0-9_]" + c_match[1] + "[^a-z0-9_]|^" + c_match[1] + "[^a-z0-9_]|[^a-z0-9_]" + c_match[1] + "$|^" + c_match[1] + "$", "i");
        }
		expression = !strictFlag ? ( value.className.indexOf( c_match[1]) != -1) : ( value.className.match( c_regExp));
		// если запрашивается элемент под определённым номером
        number = c_match[2] ? c_match[2] : null;
	// ищем определённые элементы с классом
	} else if ( c_match = element.match( regExp2) ) {
        if (strictFlag) {
            //:KLUDGE:
            c_regExp = new RegExp( "[^a-z0-9_]" + c_match[2] + "[^a-z0-9_]|^" + c_match[2] + "[^a-z0-9_]|[^a-z0-9_]" + c_match[2] + "$|^" + c_match[2] + "$", "i");
        }
		expression = !strictFlag ? (value.tagName.toLowerCase() == c_match[1] && value.className.indexOf(c_match[2]) != -1) : (value.tagName.toLowerCase() == c_match[1] && value.className.match( c_regExp));
		// если запрашивается элемент под определённым номером
        number = c_match[3] ? c_match[3] : null;
	// ищем определённые элементы без класса
	} else if ( c_match = element.match( regExp3) ) {
		expression = (value.tagName.toLowerCase() == c_match[1]);
		// если запрашивается элемент под определённым номером
        number = c_match[2] ? c_match[2] : null;
	}
    return {
        exp: expression,
        num: number
    }
}

// получаем массив, удовлетворяющий условиям
function get_elements( element, root, flags) {
    // нужно текущее значение result - объявляем здесь.
    function get_concidence( needle, haystack, flags) {
        counter = -1;
		// ищем в текущем элементе
        work_array = flags.scanChildren ? haystack.getElementsByTagName('*') : haystack.children;
        element_before = null;
        element_after = false;
		for( var j in current_children = work_array ) {
            if ( in_obj( current_children[j], result) != -1) {
                continue;
            }
            // пропускаем не числовые значения j
            value = current_children[j];
            // если в прошлый раз условие выполнилось и есть флаг !after
            if ( element_after) {
                result[result.length] = value;
                element_after = false;
            }
            // если выбранное условие выполняется, пишем в результат
            current_expression = get_expression( needle, value, flags.strict);
           if ( current_expression.exp) {
                counter ++;
                // если ищется элемент под определённым номером
                if ( current_expression.num) {
                    if ( counter == current_expression.num ) {
                        if ( flags.before) {
                            result[result.length] = element_before;
                        } else if ( flags.after) {
                            element_after = true;
                        } else {
                            result[result.length] = value;
                        }
                        break;
                    } else {
                        continue;
                    }
                } else {
                    result[result.length] = value;
                }
            }
            element_before = value;
		}
        if ( element_after) {
            result[result.length] = null;
        }
    }

	// определяем, является ли предыдущий запрошенный элемент массивом
	result = [];
	if ( root[0]) {
		for ( var i in root ) {
            get_concidence( element, root[i], flags);                
		}
	} else {
        get_concidence( element, root, flags);    
	}
    return result;
}

// аналог in_array
function in_obj( needle, haystack) {
    for ( var i in haystack) {
        if ( haystack[i] == needle) {
            return i;
        }
    }
    return -1;
}

// обрабатываем принудительные флаги
function accept_flag( root, flag) {
    if ( root == "") {
        root = null;
    }
    switch ( flag ) {
        // если результат должен быть массивом в любом случае
        case "array":
          
            if ( root && typeof root != "object") {
                root = [root];
            }

            break;
        default:
            // если массив с одним элементом, то вытаскиваем его из массива
            if ( root && root.length == 1) {
                root = root[0];
            }
    }
    return root;
}

// получаем элемент по css пути
function $( path, root) {
    // если в адресе есть id, то обрезаем адрес до него
    regexp = /^([^#]+)(#.+)$/; 
    path = trim( path).replace( regexp, "$2");
	path_elements = path.split( " ");
	root = root || document.body;
    flag = null;
    last_root = null;
	for ( var i in path_elements) {
        last_root = (root != "")? root : last_root;
        flags = {
            scanChildren: false,
            before: false,
            after: false,
            strict: false
        }
        if ( path_elements[i].indexOf( "!all") != -1) {
            flags.scanChildren = true;
            path_elements[i] = path_elements[i].replace( "!all", "");
        }
        if ( path_elements[i].indexOf( "!before") != -1) {
            flags.before = true;
            path_elements[i] = path_elements[i].replace( "!before", "");
        }
        if ( path_elements[i].indexOf( "!after") != -1) {
            flags.after = true;
            path_elements[i] = path_elements[i].replace( "!after", "");
        }
        if ( path_elements[i].indexOf( "!strict") != -1 ) {
            flags.strict = true;
            path_elements[i] = path_elements[i].replace( "!strict", "");
        }
        
		switch ( path_elements[i].substr( 0, 1) ) {  
			case ".":
				root = get_elements( path_elements[i], root, flags);
				break;
			case "#":
				root = document.getElementById( path_elements[i].substr( 1));
				break;
			case ":":
				alert( ":");
				break;
			case "!":
                flag = path_elements[i].substr( 1);
				break;
			default:
				root = get_elements( path_elements[i], root, flags);
		}
        if ( !root || root == "") {
            return undefined;
        }
	}
    return accept_flag( root, flag);
}

// копируем контент элемента
function copy_element_content( fromElem, toElem) {
	tempArray = new Array();
    
	childArray = fromElem.childNodes;
	for ( var i in childArray) {
		if ( childArray[i].nodeType && childArray[i].nodeType == 1) {
			tempArray[i] = childArray[i];
		}
	}
	for ( var i in tempArray) {
		toElem.appendChild( tempArray[i]);
	}
}

// удаляем дочерние элементы
function delete_children( node) {
	while ( node.firstChild) {
		node.removeChild( node.firstChild);
	}
}

// выдаём "координаты" ячейки в таблице
function get_table_coord( tdElement) {
    trElementArray = getElementsArray( tdElement.parentNode, "td");
    tableElementArray = getElementsArray( tdElement.parentNode.parentNode, "tr");
    row = 0;
	col = 0;

    for ( var i in tableElementArray) {
        // в этой ли строке находится искомый элемент?
        if ( tableElementArray[i] == tdElement.parentNode) {
            break;
        } else {
            row ++;
        }
    }
    
	for ( var i in trElementArray) {
	   // в этом ли столбце находится искомый элемент
        if ( trElementArray[i] == tdElement) {
            break;
        } else {
            col ++;
        }
	}

	return { "x": col, "y": row}
}

// переключатель видимости элемента ( если мягкий, то через visibility, иначе через display)
function show_element( element, prop, soft) {
    soft = soft || false;
	prop = prop || "block";
    if ( element.style.display == "none" && !soft || element.style.visibility == "hidden" && soft) {
        if ( !soft) {
            element.style.display = prop;
        }
        element.style.visibility = "visible";
    } else {
        if ( !soft) {
            element.style.display = "none";
        }
        element.style.visibility = "hidden";
    }
}

// закрыть элемент в курсоре
function hide_element_in_cursor() {
	if ( g_current_visible) {
		g_current_visible.style.display = "none";
	}
}

// скрыть элемент в курсоре через некоторое время
function close_element_in_cursor() {
	var timeOut = window.setTimeout( "hide_element_in_cursor()", 350);
}

// поместить абсолютный элемент в позицию курсора
function show_element_in_cursor( div, event) {
	hide_element_in_cursor();
	
 	if ( div && div.style.display != "block") {
		g_current_visible = div;
		div.style.display = "block";
	}
	var wwidth = (window.innerWidth)?window.innerWidth: ((document.all)?document.body.offsetWidth:null);
	if (!event) event=window.event;
	x = (event.clientX) ?  event.clientX : ((event.pageX) ? event.pageX : event.screenX);
	y = (event.clientY) ? (event.clientY + 15) : (event.pageY + 15);
	if ( document.documentElement.scrollTop == 0) {
		y += document.body.scrollTop;
	} else {
		y += document.documentElement.scrollTop;
	}
	
	if ( x + div.offsetWidth + 20 >= wwidth) {
		x -= div.offsetWidth;
	}
	div.style.top = y+"px";
	div.style.left = x+"px";
}

// отцентровать элемент по вертикали и горизонтали
function centre_element( element) {
    if ( !g_all_width) {
        g_all_width = document.body.scrollWidth || document.documentElement.scrollWidth;
    }
    if ( !g_all_height) {
        g_all_height = ( document.documentElement.offsetHeight < document.body.offsetHeight) ? document.documentElement.offsetHeight: document.body.offsetHeight;
    }
    if ( !g_all_scroll) {
       g_all_scroll = document.body.scrollHeight || document.documentElement.scrollHeight;
    }
    element.style.left = Math.ceil( g_all_width / 2 - element.offsetWidth / 2);
    element.style.top = Math.ceil( g_all_height / 2 - element.offsetHeight / 2) + ( !document.documentElement.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop);
}

// обрезаем начальные и конечные пробелы
function trim( string) {
	var regExp = /^(\s)*(.*)(\s)*$/;
	return string.match( regExp)[2];
}

// получаем значение кук  и помещаем их в глобальный массив $_COOKIE
$_COOKIE = new Object();
paar_array = document.cookie.split( ";");

for ( var i in paar_array ) {
	current_values = paar_array[i].split( "=");
	$_COOKIE[trim(current_values[0])] = current_values[1];
}

function get_table( obj) {
    txt = "<table width=100% border=1 style='border-collapse:collapse'>";
    for ( var i in obj ) {
        if ( typeof( obj[i]) == "object" ) {
            txt += "<tr><td width=10%>"+ i +"<span style='color:gray'>("+ typeof( i) +")</span></td><td width=90%>"+ get_table( obj[i]) +"</td></tr>";
        } else {
            txt += "<tr><td width=10%>"+ i +"<span style='color:gray'>("+ typeof( i) +")</span></td><td width=90%>"+ obj[i] +"</td></tr>";
        }
    }
    txt += "</table>";
    return txt;
}

function get_alert( obj, level, stop_level) {
	stop_level = stop_level || 1;
    txt = "";
    paddingLeft = "";
    for ( var i = 0; i < level; i++) {
        paddingLeft += "\t\t";
    }
    for ( var i in obj ) {
        if ( typeof( obj[i]) == "object" && level < stop_level) {
            txt += paddingLeft + i +" ("+ typeof( i) +"):\n"+ get_alert( obj[i], ( level + 1) ) +"\n";
        } else {
            txt += paddingLeft + i +"("+ typeof( i) +"):\t"+ obj[i] +"\n";
        }
    }
    return txt;
}

// вытаскиваем свойства объекта
function alert_obj( obj) {
    txt = get_table( obj);
    if ( txt.length < 6000) {
        txt = get_alert( obj, 0);
        alert( txt);
    } else {
        win = window.open();
        win.document.write( txt);
    }
}

// вместо body.onload=...
function bind_ready( handler_unload){
	var called = false
	function ready() {
		if (called) return
		called = true
		handler_unload();
	}
	if ( document.addEventListener ) {
		document.addEventListener( "DOMContentLoaded", function(){
			ready()
		}, false )
	} else if ( document.attachEvent ) {
		if ( document.documentElement.doScroll && window == window.top ) {
			function tryScroll(){
				if (called) return
				if (!document.body) return
				try {
					document.documentElement.doScroll("left")
					ready()
				} catch(e) {
					setTimeout(tryScroll, 0)
				}
			}
			tryScroll()
		}
		document.attachEvent( "onreadystatechange", function(){
			if ( document.readyState === "complete" ) {
				ready()
			}
		})
	}
    if (window.addEventListener) {
        window.addEventListener('load', ready, false)
    } else if (window.attachEvent) {
        window.attachEvent('onload', ready)
    }
    /*  else  // (4.1)
        window.onload=ready
	*/
}

// получаем порядковый номер элемента в родителе
function get_element_number( elem) {
    elements = $( elem.tagName.toLowerCase(), elem.parentNode);
    counter = 0;
    for ( var i in elements) {
        if ( elements[i] == elem) {
            return counter;
        }
        counter ++;
    }
    return false;
}

// position:fixed для ie 
function fixed(e, pos) {
    if (/MSIE (5\.5|6).+Win/.test(navigator.userAgent))
    {
        e.style.position = 'absolute';
        return (document.documentElement.scrollTop + pos) + 'px';
    }
    else e.style.top = pos + 'px';
}

// обработка событий
Event = (function() {

  var guid = 0

  function fixEvent(event, obj) {
	event = event || window.event

    if ( event.isFixed ) {
      return event
    }
    event.isFixed = true

    event.preventDefault = event.preventDefault || function(){this.returnValue = false}
    event.stopPropagation = event.stopPropagaton || function(){this.cancelBubble = true}
    if (!event.target) {
        event.target = event.srcElement;
    }
    if ( !event.currentTarget ) {
        event.currentTarget = obj;
    }
    if (!event.relatedTarget && event.fromElement) {
        event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
    }
    if ( event.pageX == null && event.clientX != null ) {
        var html = document.documentElement, body = document.body;
        event.pageX = event.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
        event.pageY = event.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
    }

    if ( !event.which && event.button ) {
        event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
    }

    if ( !event.which && !event.button && event.keyCode) {
	event.which = event.keyCode;
    }

	return event
  }
  function commonHandle(event) {
    event = fixEvent(event, this)

    var handlers = this.events[event.type]

	for ( var g in handlers ) {
      var handler = handlers[g]

      var ret = handler.call(this, event)
      if ( ret === false ) {
          event.preventDefault()
          event.stopPropagation()
      }
    }
  }

  return {
    add: function(elem, type, handler) {
      if (elem.setInterval && ( elem != window && !elem.frameElement ) ) {
        elem = window;
      }

      if (!handler.guid) {
        handler.guid = ++guid
      }

      if (!elem.events) {
        elem.events = {}
		elem.handle = function(event) {
		  if (typeof Event !== "undefined") {
			return commonHandle.call(elem, event)
		  }
        }
      }

      if (!elem.events[type]) {
        elem.events[type] = {}

        if (elem.addEventListener)
		  elem.addEventListener(type, elem.handle, false)
		else if (elem.attachEvent)
          elem.attachEvent("on" + type, elem.handle)
      }

      elem.events[type][handler.guid] = handler
    },

    remove: function(elem, type, handler) {
      var handlers = elem.events && elem.events[type]

      if (!handlers) return

      delete handlers[handler.guid]

      for(var any in handlers) return
	  if (elem.removeEventListener)
		elem.removeEventListener(type, elem.handle, false)
	  else if (elem.detachEvent)
		elem.detachEvent("on" + type, elem.handle)

	  delete elem.events[type]


	  for (var any in elem.events) return
	  try {
	    delete elem.handle
	    delete elem.events
	  } catch(e) { // IE
	    elem.removeAttribute("handle")
	    elem.removeAttribute("events")
	  }
    }
  }
}())

// перетаскивание элемента
Drag = {
    current: {
        obj         : null,
        inside_x    : null,
        inside_y    : null,
        cursor      : null
    },
    start: function( event) {
        if ( event.target.tagName.toLowerCase() != "input" && event.target.tagName.toLowerCase() != "textarea" && event.target.tagName.toLowerCase() != "textarea" && event.target.scrollHeight <= event.target.offsetHeight) {
            Drag.current.inside_x = event.clientX - event.currentTarget.offsetLeft;
            Drag.current.inside_y = event.clientY - event.currentTarget.offsetTop;
            Drag.current.obj = event.currentTarget;
            Drag.current.cursor = !event.currentTarget.style.cursor || event.currentTarget.style.cursor == "move" ? "default" : event.currentTarget.style.cursor;
            event.currentTarget.style.cursor = "move";
        }
    },
    process: function( event) {
        if ( Drag.current.obj == event.currentTarget && event.target.tagName.toLowerCase() != "input" && event.target.tagName.toLowerCase() != "textarea" && event.target.scrollHeight <= event.target.offsetHeight) {
            event.preventDefault();
            event.stopPropagation();
            if ( event.currentTarget.offsetWidth < document.body.offsetWidth ) {
                xExp = (event.clientX + event.currentTarget.offsetWidth - Drag.current.inside_x <= g_all_width && event.clientX - Drag.current.inside_x >= 0 );
                yExp = (event.clientY + event.currentTarget.offsetHeight - Drag.current.inside_y <= g_all_scroll && event.clientY - Drag.current.inside_y >= 0);
            } else {
                xExp = (- event.currentTarget.offsetLeft + document.body.offsetWidth - (event.clientX - Drag.current.inside_x) < event.currentTarget.offsetWidth && event.currentTarget.offsetLeft + (event.clientX - Drag.current.inside_x) <= 0);
                yExp = (document.body.offsetHeight - (event.clientY - Drag.current.inside_y) < event.currentTarget.offsetHeight && event.currentTarget.offsetTop + (event.clientY - Drag.current.inside_y) <= 0);
            }
            if ( xExp && !Drag.current.clearBorder || true && Drag.current.clearBorder) {
                event.currentTarget.style.left = (event.clientX - Drag.current.inside_x) + "px";
            }
            if ( yExp && !Drag.current.clearBorder || true && Drag.current.clearBorder) {
                event.currentTarget.style.top = (event.clientY - Drag.current.inside_y) + "px";
            }
        }
    },
    stop: function( event) {
        Drag.current.obj = null;
        event.currentTarget.style.cursor = Drag.current.cursor;
    },
/*    out: function( event) {
        if ( event.relatedTarget == Drag.current.obj) {
            Drag.current.obj = null;
            event.currentTarget.style.cursor = Drag.current.cursor;
        }
    },*/
    add: function( element, clearBorder) {
        Drag.current.clearBorder = clearBorder || false;
        if ( !g_all_width) {
            g_all_width = document.body.scrollWidth || document.documentElement.scrollWidth;
        }
        if ( !g_all_scroll) {
           g_all_scroll = document.body.scrollHeight || document.documentElement.scrollHeight;
        }
        Event.add( element, "mousedown", Drag.start); 
        Event.add( element, "mouseup", Drag.stop); 
        Event.add( element, "mouseout", Drag.stop); 
        Event.add( element, "mousemove", Drag.process); 
    },
    remove: function( element) {
        Event.remove( element, "mousedown", Drag.start); 
        Event.remove( element, "mouseup", Drag.stop); 
        Event.remove( element, "mouseout", Drag.stop); 
        Event.remove( element, "mousemove", Drag.process); 
    }
}


// спёртая откуда-то функция определения абсолютного положения элемента
function getOffsetSum(elem) {
	var top=0;
	var left = 0;
	while ( elem) {
		top = top + parseInt(elem.offsetTop);
		left = left + parseInt(elem.offsetLeft);
		elem = elem.offsetParent;
	}
	    return {top: top, left: left}
}

function getOffsetRect(elem) {
	var box = elem.getBoundingClientRect();
	
	var body = document.body;
	var docElem = document.documentElement;
	
	var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
	var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
	
	var clientTop = docElem.clientTop || body.clientTop || 0;
	var clientLeft = docElem.clientLeft || body.clientLeft || 0;
	
	var top  = box.top +  scrollTop - clientTop;
	var left = box.left + scrollLeft - clientLeft;
	
	return { top: Math.round(top), left: Math.round(left) }
}

function getOffset(elem) {
	if ( elem.getBoundingClientRect) {
		return getOffsetRect(elem);
	} else {
		return getOffsetSum(elem);
	}
}

function show_title( txt, event) {
	div = $( "#common_title");
 	if ( div && div.style.display != "block") {
		div.style.display = "block";
	}
	var wwidth = (window.innerWidth)?window.innerWidth: ((document.all)?document.body.offsetWidth:null);
	if (!event) event=window.event;
	x = (event.clientX) ?  event.clientX : ((event.pageX) ? event.pageX : event.screenX);
	y = (event.clientY) ? (event.clientY + 15) : (event.pageY + 15);
	if ( document.documentElement.scrollTop == 0) {
		y += document.body.scrollTop;
	} else {
		y += document.documentElement.scrollTop;
	}
	
	if ( x + div.offsetWidth + 20 >= wwidth) {
		x -= div.offsetWidth;
	}
	div.style.top = y+"px";
	div.style.left = x+"px";
	
	$( "#common_title").innerHTML = txt;
}

function hide_title() {
	$( "#common_title").style.display = "none";
}
