/* Объявление общих классов*/
/*  Класс наблюдатель.
	Являясь прототипом объекта, позволяет ему назначать себе наблюдателей и
	оповещать их о происходящих событиях */
function ClassObservable() {
	// НЕЛЬЗЯ ДОБАВЛЯТЬ this.observers = [] В ПРОТОТИП!!! Иначе наблюдателем будут не объекты, а прототип
	// Метод, добавляющий наблюдателя
	this.addObserver = function ($event_type, $observer, $method){
		if (!this.observers) this.observers = [];                    // Если у объекта ещё нет списка событий - создать его
		$event_type = $event_type.toLowerCase();                     // Все события должны быть написаны в нижнем регистре для унификации
		if (!this.observers[$event_type]) this.observers[$event_type] = []; // Если нет массива для данного типа событий, то необходимо его создать
		$length = this.observers[$event_type].length;                       // Вычисляем длину массива
		this.observers[$event_type][$length] = [];
		this.observers[$event_type][$length].observer = $observer;                   // Добавляем наблюдатель в конец массива
		if ($method) this.observers[$event_type][$length].method = $method;          // Добавляем наблюдатель в конец массива
	}
	this.detachObserver = function ($event, $observer) {

		var $observers, $i, $length;
		for ($i = 0, $observers = this.observers[$event], $lenght = $observers.length; $i < $lenght; $i++) {
	    	if  ($observer == $observers[$i].observer) $observers.splice($i, 1);
	    }
	}
	// Метод проверяет, являетсля ли уже объект наблюдателем данного события у данного объекта
	this.exist = function ($event, $observer) {
		var $observers, $i, $length;
		for ($i = 0, $observers = this.observers[$event], $lenght = $observers.length; $i < $lenght; $i++) {
	    	if  ($observer == $observers[$i]) return $i;
	    }
	    return false;
	}
	// Оповещает наблюдателей о происходящих событиях
	this.notify = function ($event) {                 // $event - тип события
		var $arguments, $observers, $observer, $i, $length;
		$arguments = arguments;                       // Получаем массив аргументов, с которыми был вызван метод notify
		$event = $event.toLowerCase();                // Для унификации переводим название события в нижний регистр
		if (!this.observers) return false;            // Если нет массива обработчиков,
		if (!this.observers[$event]) return false;    //  или нет массива для обработчиков данного типа - вернуть ложь
		for ($i = 0, $observers = this.observers[$event], $length = $observers.length; $i < $length; $i++) {
			$observer = $observers[$i];
        	if ($observer.observer instanceof Function) $observer.observer($event, $arguments);
			else if ($observer.observer[$observer.method] instanceof Function) $observer.observer[$observer.method]($event, $arguments);
			else if ($observer.observer.update instanceof Function) $observer.observer.update($event, $arguments);
		}
	}
}

/*  Класс, представляющий из себя набор для работы элемента с DOM */
function ClassDomObject() {
	// Возворащает вертикальную координату объекта, относительно верхней границы страницы
	this.getTopOffset = function ($object){
		var $offset = 0;
		this.topOffset = 0;
		this.leftOffset = 0;
		while ($object) {
			$offset += $object.offsetTop;
			this.topOffset += $object.offsetTop;
			this.leftOffset += $object.offsetLeft;
			$object = $object.offsetParent;
		}
		return $offset;
	}
	// Возворащает горизонтальную координату объекта, относительно левой границы страницы
	this.getLeftOffset = function ($object){
		var $offset = 0;
		this.topOffset = 0;
		this.leftOffset = 0;
		while ($object) {			$offset += $object.offsetLeft;
			this.topOffset += $object.offsetTop;
			this.leftOffset += $object.offsetLeft;
			$object = $object.offsetParent;
		}
		return $offset;
	}
	this.placeInto = function ($place, $this_body_object) {
   		var $body = $this_body_object||this.body;
   		this.body = $place.appendChild($body);
		this.notify('onElementPlacedInDom');
	}
	this.placeBefore = function ($place, $this_body_object) {
   		var $body = $this_body_object||this.body;
		var $parent = $place.parentNode;
   		this.body = $parent.insertBefore($body, $place);
		this.notify('onElementPlacedInDom');
	}
	this.placeAfter = function ($place, $this_body_object) {
   		var $body = $this_body_object||this.body;
		var $parent = $place.parentNode;
    	if ($next = $place.nextSibling) {
    		this.body = $parent.insertBefore($body, $next);
    	} else {
    		this.body = $parent.appendChild($body);
    	}
		this.notify('onElementPlacedInDom');
	}
}
ClassDomObject.prototype = new ClassObservable();

// Treeton Style Studio Global Document Administrator
// Глобальный объект для управления документом
function ClassDocumentAdministrator () {
    var $tdtime = new Date();
    var oThis = this;
    this.time = $tdtime.getTime();
    this.id = 'TSSGDA';
    this.init = function() {
	    this.body = document.getElementsByTagName('body')[0];
    	this.body.object = this;
    	this.body.onmouseup = function () {this.object.relaseMouse();}
    	this.body.onclick = function () {this.object.click();}
	    this.body.onmouseover = function () {this.object.mouseover();}
	    document.onkeypress = function (event)
	    {
	    	if (!event) event = window.event;
	    	var key = event.keyCode ? event.keyCode : event.which ? event.which : null;
			oThis.notify('onkeypress', key);
		}
    }
    this.click = function () {
    	this.notify('onClick');
    }
    this.relaseMouse = function () {
    	this.notify('onMouseUp');
    }
    this.mouseover = function () {
    	this.notify('onmouseover');
    }
	// Размещает узел объекта $body внутри элемента с ID = $id
	this.placeIntoId = function ($body, $id) {
		var $node = document.getElementById($id);
   		$node.appendChild($body);
		this.notify('onElementPlacedInDom');
		this.notify('onAddedContent', $id);
	}
	// Размещает узел объекта $body до элемента с ID = $id
	this.placeBeforeId = function ($body, $id) {
		var $node = document.getElementById($id);
		var $parent = document.getElementById($id).parentNode;
   		$parent.insertBefore($body, $node);
		this.notify('onElementPlacedInDom');
	}
	// Размещает узел объекта $body после элемента с ID = $id
	this.placeAfterId = function ($body, $id) {
		var $node = document.getElementById($id);
		var $parent = document.getElementById($id).parentNode;
    	if ($next = $node.nextSibling) {
    		$parent.insertBefore($body, $next);
    	} else {
    		$parent.appendChild($body);
    	}
		this.notify('onElementPlacedInDom');
	}
}
ClassDocumentAdministrator.prototype = new ClassDomObject();
TSSGDA = new ClassDocumentAdministrator ();

window.onload = init;

function init() {
/*	$ARTICLE = document.getElementById('article');
	if ($ARTICLE) selectTermins ();
	$SCHEME = document.getElementById('scheme');
	if ($SCHEME) initScheme();
	if (typeof(renderOrderForm) != "undefined") renderOrderForm();*/
	TSSGDA.init();
	TSSGDA.notify('onload');
}

function changeEnding(sStr, sNewEnding) {
	return  sStr.replace( /-\w+($|\.\w{1,5}$)/, "-"+sNewEnding+"$1");
}

function getEnding(sStr) {
	var r = /-(\w+)($|\.\w{1,5}$)/;
	var arr = r.exec(sStr);
	return arr[1];
}


function echo ($message) {	var $mw = document.getElementById('messagi');
	if (!$mw) {		$mw = document.createElement('div');
		$mw = document.body.appendChild($mw);
		$mw.id = 'messagi';
	}
    $mw.innerHTML += $message + '<br/>';
}

function stopBubble(oEvent)
{
   	if (!oEvent) oEvent = window.event;
	if (oEvent.stopPropagation) oEvent.stopPropagation(); // для DOM-совместимых браузеров
	else window.event.cancelBubble = true; //для IE
}

