/* Copyright (c) 2007 Onlyweb Studio | http://www.onlyweb.ru/ */
/*

Author: Miha Zimin 

Big thanks to http://prototypejs.org/

From Russia with love!

*/


var SmartObject = Class.create();
SmartObject.prototype = {

	initialize: function(options) {
		this.options = options;
	},
	
	registerEventForElements: function(optionsName, eventType, element) {
		var _this = this;
		var capitalizedEventType = eventType.capitalize();
		var e = optionsName + capitalizedEventType + 'Event';
		if(!this[optionsName + capitalizedEventType]) {
			throw ('method ' + optionsName + capitalizedEventType + ' isn\'t define');
		}
		if(!this[e]) {
			this[e] = this[optionsName + capitalizedEventType].bindAsEventListener(this);
		}
		element.getElementsByClassName(this.options[optionsName + 'Class']).each(function(el) {
			Event.observe(el, eventType, _this[e]);
		});
	},
	
	getParentElement: function(optionsName, element) {
		var parentClass = this.options[optionsName + 'Class'];
		//alert(parentClass);
		while(!element.hasClassName(parentClass)) {
				element = element.up();
				//alert(element.className);
		}
		return element;
	}
}


var App = {};

App.NewsWithZoomedImages = Class.create();
App.NewsWithZoomedImages.prototype = Object.extend(new SmartObject(), {
	/**
	*
	* container
	* image0Class
	* image1Class
	* normalWidth
	* normalHeight
	* bigWidth
	* bigHeight
	* zoomedImageContainerClass
	* newsClass
	* newsDescriptionClass
	* newsDescriptionReferenceClass
	*
	*/
	initialize: function(options) {
		this.options = options;
		this.container = $(options.container);
		
		this.registerEventForElements('image0', 'mouseover', this.container);
		this.registerEventForElements('image1', 'mouseout', this.container);
		
		// this.registerEventForElements('newsDescriptionReference', 'mouseover', this.container);
		// this.registerEventForElements('newsDescriptionReference', 'mouseout', this.container);
		
	},
	
	getImages: function(zoomedImageContainer) {
		var result = [];
		result[0] = zoomedImageContainer.getElementsByClassName(this.options.image0Class)[0];
		result[1] = zoomedImageContainer.getElementsByClassName(this.options.image1Class)[0];
		return result;
	},
	
	setNormalImage: function(zoomedImageContainer) {
		this.getImages(zoomedImageContainer)[0].show();
		this.getImages(zoomedImageContainer)[1].hide();
	},
	
	setBigImage: function(zoomedImageContainer) {
		this.getImages(zoomedImageContainer)[0].hide();
		this.getImages(zoomedImageContainer)[1].show();
	},
	
	image0Mouseover: function(event) {
		var element = Event.element(event);
		this.setBigImage(this.getParentElement('zoomedImageContainer', element));
	},
	
	image1Mouseout: function(event) {
		var element = Event.element(event);
		this.setNormalImage(this.getParentElement('zoomedImageContainer', element));
	},
	
	newsDescriptionReferenceMouseover: function(event) {
		var element = Event.element(event);
		//alert(element.constructor);
		var news = this.getParentElement('news', element);
		var zoomedImageContainer = news.getElementsByClassName(this.options.zoomedImageContainerClass)[0];
		this.setBigImage(zoomedImageContainer);
	},
	
	newsDescriptionReferenceMouseout: function(event) {
		var element = Event.element(event);
		var news = this.getParentElement('news', element);
		var zoomedImageContainer = news.getElementsByClassName(this.options.zoomedImageContainerClass)[0];
		this.setNormalImage(zoomedImageContainer);
	}
});


App.BottomMainMenu = Class.create();
App.BottomMainMenu.prototype = Object.extend(new SmartObject(), {

	/**
	*
	* container
	* headerLiClass
	* currentHeaderLiClass
	* headerContentClass
	* referenceHeaderLiClass
	* currentReferenceHeaderLiClass
	* referenceHeaderContentClass
	* subMenuUlClass
	*
	*/
	initialize: function(options) {
		this.options = options;	
		this.container = $(options.container);
		
		this.registerEventForElements('headerContent', 'mouseover', this.container);
		this.registerEventForElements('headerContent', 'mouseout', this.container);
		
		this.registerEventForElements('referenceHeaderContent', 'mouseover', this.container);
		this.registerEventForElements('referenceHeaderContent', 'mouseout', this.container);
		
		this.registerEventForElements('subMenuUl', 'mouseover', this.container);
		this.registerEventForElements('subMenuUl', 'mouseout', this.container);
		
		this.dontHide = [];
	},
	
	subMenuUlMouseover: function(event) {
		var element = Event.element(event);
		if(element.hasClassName(this.options.subMenuUlClass)) {
			d('Настоящий subMenuUlMouseover');
			var ul = element;
		} else {
			d('Внутренний subMenuUlMouseover');
			var ul = this.getParentElement('subMenuUl', element);
		}
		var id = ul.id;
		this.dontHide[id] = true;
	},
	
	subMenuUlMouseout: function(event) {
		var element = Event.element(event);
		if(element.hasClassName(this.options.subMenuUlClass)) {
			d('Настоящий subMenuUlMouseout');
			var ul = element;
		} else {
			d('Внутренний subMenuUlMouseout');
			var ul = this.getParentElement('subMenuUl', element);
		}
		var id = ul.id;
		this.dontHide[id] = false;
		// Дадим пользователю полсекунды на то, что он может вернуться в меню
		new PeriodicalExecuter(this.hideCurrentTimer.bind(this, id), 0.5);
		
	},
	
	headerContentMouseover: function(event) {
		d('headerContentMouseover');
		var element = Event.element(event);
		var li = this.getParentElement('headerLi', element);
		var ul = li.getElementsByClassName(this.options.subMenuUlClass)[0];
		var id = ul.id;
		this.dontHide[id] = true;
		this.showSubMenus();
	},
	
	referenceHeaderContentMouseover: function(event) {
		d('referenceHeaderContentMouseover');
		var element = Event.element(event);
		var li = this.getParentElement('referenceHeaderLi', element);
		li.addClassName(this.options.currentReferenceHeaderLiClass);
		this.showSubMenus();
	},
	
	referenceHeaderContentMouseout: function(event) {
		d('referenceHeaderContentMouseout');
		var element = Event.element(event);
		var li = this.getParentElement('referenceHeaderLi', element);
		li.removeClassName(this.options.currentReferenceHeaderLiClass);
	},
	
	headerContentMouseout: function(event) {
		d('headerContentMouseout');
		var element = Event.element(event);
		var li = this.getParentElement('headerLi', element);
		var ul = li.getElementsByClassName(this.options.subMenuUlClass)[0];
		var id = ul.id;
		this.dontHide[id] = false;
		// Дадим пользователю полсекунды на то, что он может вернуться в меню
		new PeriodicalExecuter(this.hideCurrentTimer.bind(this, id), 0.5);
	},
	
	hideCurrentTimer: function(id, pe) {
		d('hideCurrentTimer, id: ' + id);
		if(this.dontHide[id] != true) {
			var ul = $(id);
			var headerLi = this.getParentElement('headerLi', ul);
			this.hideList(ul);
			headerLi.removeClassName(this.options.currentHeaderLiClass);
		}
		pe.stop();
		pe = null;
	},
	
	showSubMenus: function() {
		var _this = this;
		this.container.getElementsByClassName(this.options.subMenuUlClass).each(function(element) {
			if(element.id != '') {
				var id = element.id;
				var ul = $(id);
				var headerLi = _this.getParentElement('headerLi', ul);
				if(_this.dontHide[id] != true) {
					_this.hideList(ul);
					headerLi.removeClassName(_this.options.currentHeaderLiClass);
				} else {
					_this.showList(ul);
					headerLi.addClassName(_this.options.currentHeaderLiClass);
				}
			}
		});
	},
	
	showList: function(ul) {
		ul.show();
		/*
		if(!ul.visible()) {
			Effect.Appear(ul, {
				duration: 0.5,
				from: 0.0,
				to: 1.0
			});
		}
		*/
	},
	
	hideList: function(ul) {
		ul.hide();
		/*
		if(ul.visible()) {
			Effect.Appear(ul, {
				duration: 0.5,
				from: 1.0,
				to: 0.0
			});
			new PeriodicalExecuter(function(pe) {
				ul.hide();
				pe.stop();
			}, 0.5);
		}
		*/
	}

});


App.InputsWithTitle = Class.create();
App.InputsWithTitle.prototype = Object.extend(new SmartObject(), {
	/**
	*
	* inputWithTitleClass
	* emptyInputWithTitleClass
	*
	*/
	initialize: function(options) {
		var _this = this;
		this.options = options;
		
		this.registerEventForElements('inputWithTitle', 'focus', document);
		this.registerEventForElements('inputWithTitle', 'blur', document);
		
		document.getElementsByClassName(this.options.inputWithTitleClass).each(function(input) {
			/* TODO: correct this bad style, it's terrible to call event handler function manually */
			_this.inputWithTitleBlur({
				target: input
			});
		});
		
		window.onunload = this.clearInputs.bind(this);
	},
	
	inputWithTitleFocus: function(event) {
		var element = Event.element(event);
		if(element.hasActuallyPasswordType == true) {
			element.setAttribute('type', 'password');
		}
		if(element.hasClassName(this.options.emptyInputWithTitleClass)) {
			element.addClassName(this.options.inputWithTitleClass);
			element.removeClassName(this.options.emptyInputWithTitleClass);
			element.value = "";
		}
	},
	
	inputWithTitleBlur: function(event) {
		var element = Event.element(event);
		if(element.value == '') {
			var type = element.getAttribute('type').toLowerCase();
			if(type == 'password') {
				// не поддерживается в IE
				// element.setAttribute('type', 'text');
				element.hasActuallyPasswordType = true;
			}
			var title = element.getAttribute('title');
			if(title == '') {
				throw('No title atribute for element with class ' + this.options.inputWithTitleClass);
			}
			element.addClassName(this.options.emptyInputWithTitleClass);
			element.removeClassName(this.options.inputWithTitleClass);
			element.value = title;
		}
	},
	
	clearInputs: function() {
		/* Iterate all empty inputs and clean their value */
		document.getElementsByClassName(this.options.emptyInputWithTitleClass).each(function(input) {
			input.value = '';
		});
	}
});


App.TopMainMenu = Class.create();
App.TopMainMenu.prototype = {
	/**
	*
	* menu
	* innerUlClass
	* innerLastLiClass
	*
	*/
	initialize: function(options) {
		this.options = options;
		this.menu = $(options.menu);
		window.onresize = this.windowResize.bind(this);
		
		/* TODO: it's bad style */
		this.windowResize();
	},
	
	getBodyWidth: function() {
		return document.documentElement.clientWidth || document.body.clientWidth;
	},
	
	windowResize: function(event) {
		var _this = this;
		var bodyWidth = this.getBodyWidth();
		if(bodyWidth > 990) {
			var margin = Math.round((bodyWidth*bodyWidth*bodyWidth) / 138614142);
		} else {
			var margin = 7;
		}
		this.menu.getElementsByClassName(this.options.innerUlClass).each(function(ul) {
			$A(ul.getElementsByTagName('li')).each(function(li) {
				if(!li.hasClassName(_this.options.innerLastLiClass)) {
					li.style.marginRight = margin.toString() + 'px';
				}
			});
		});
	}
};


App.Map = Class.create();
App.Map.prototype = {
	/**
	*
	* mapElement
	* html
	* latitude
	* longitude
	*
	*/
	initialize: function(options) {
		var _this = this;
		this.options = options;
		
		window.onload = function() {
			if (GBrowserIsCompatible()) {
				_this.map = new GMap2($(_this.options.mapElement));
				_this.map.addControl(new GSmallMapControl());
				_this.map.addControl(new GMapTypeControl());
				_this.point = new GLatLng(_this.options.latitude, _this.options.longitude);
				_this.map.setCenter(_this.point, 16, G_HYBRID_MAP);
				_this.marker = new GMarker(_this.point);
				GEvent.bind(_this.marker, "click", _this, _this.markerClick);
				_this.map.addOverlay(_this.marker);
				_this.marker.openInfoWindowHtml(_this.options.html);
			}
		};
		
		window.onunload = function() {
			GUnload();
		};
	},
	
	markerClick: function() {
		this.marker.openInfoWindowHtml(this.options.html);
	}
}


d = function() {}

/*

d = function(str) {
	$('debugger').innerHTML = str + '\r\n' + $('debugger').innerHTML;
}

*/