var App = {
	getCoordinates: function() {
		var coords = $("page-container").getCoordinates();
		var windowHeight = window.getHeight();
		
		if (coords.height < windowHeight)
		{
			coords.height = windowHeight;
			coords.bottom = coords.top + coords.height;
		}
		
		return coords;
	},
	
	_showContactForm: function() {
		if (!this.contactForm)
			this.contactForm = new ContactForm("contact-form", {
				"centerOnScroll": true
			});
		this.contactForm.show();
		
		return this;
	}
};

/**
 * Class: Ticker
 */
var Ticker = new Class({
	options: {
		tickerClass: "tie-ticker",
		autoStart: true,
		speed: 1500,
		delay: 5000,
		direction: "vertical"
	},
	
	initialize: function(el, options) {
		this.setOptions(options);
		
		this.el = $(el);
		if (this.options.tickerClass)
			this.el.addClass(this.options.tickerClass);
		this.items = this.el.getElements("li");
		
		var size = this._calculateSize();
		
		this.el.setStyles({
			position: "absolute",
			top: 0,
			left: 0,
			width: size.width,
			height: size.height
		});
		
		this._fx = new Fx.Styles(this.el, {
			duration: this.options.speed,
			onComplete: function() {
				this.items[(this._current == 0 ? this.items.length : this._current) - 1].injectInside(this.el);
				
				this.el.setStyles({
					left: 0,
					top: 0
				});
			}.bind(this)
		});
		
		this._current = 0;
		
		if (this.options.autoStart)
			this.start();
	},
	
	start: function() {
		if (!this._disposed && !this._timer)
			this._timer = this._roll.periodical(this.options.delay, this);
		
		return this;
	},
	
	stop: function() {
		if (!this._disposed && this._timer) {
			this._fx.stop();
			this._timer = $clear(this.timer);
		}
		
		return this;
	},
	
	destroy: function() {
		if (!this._disposed) {
			this.stop();
			
			this._disposed = true;
		}
	},
	
	_roll: function() {
		if (++this._current >= this.items.length)
			this._current = 0;
		
		var pos = this.items[this._current];
		
		this._fx.start({
			top: -pos.offsetTop,
			left: -pos.offsetLeft
		});
		
		return this;
	},
	
	_calculateSize: function() {
		var size = {width: 0, height: 0};
		
		if (this.options.direction.toLowerCase() == "horizontal") {
			size.height = this.el.getSize().size.y;
			
			this.items.each(function(li, index) {
				size.width += li.getSize().size.x;
			});
		}
		else {
			size.width = this.el.getSize().size.x;
			
			this.items.each(function(li, index) {
				size.height += li.getSize().size.y;
			});
		}
		
		return size;
	}
});
Ticker.implement(new Options, new Events);

/**
 * Class: Overlay
 */
var Overlay = new Class({
	options: {
		overlayClass: "tie-overlay",
		ownerElement: false,
		
		onShow: function(overlay) {
			overlay.setStyle("display", "");
		},
		onHide: function(overlay) {
			overlay.setStyle("display", "none");
		},
		onDestroy: Class.empty
	},
	
	initialize: function(options) {
		this.setOptions(options);
		
		this._visible = false;
		this._bound = {
			updateBounds: this._updateBounds.bind(this)
		};
		
		this._build();
	},
	
	_build: function() {
		this._overlay = new Element("div", {
			"styles": {
				"display": "none"
			}
		});
		if (this.options.overlayClass)
			this._overlay.addClass(this.options.overlayClass);
		this._overlay.inject(document.body);
	},
	
	show: function() {
		if (!this._visible) {
			this._visible = true;
		
			this._updateBounds();
			
			if (this.options.ownerElement)
				this._overlay.setStyle("z-index", $(this.options.ownerElement).getStyle("z-index") - 2);
			
			Window.addEvent("resize", this._bound.updateBounds);
			
			this.fireEvent("onShow", [this._overlay]);
		}
		
		return this;
	},
	
	hide: function() {
		if (this._visible) {
			this._visible = false;
			
			Window.removeEvent("resize", this._bound.updateBounds);
			
			this.fireEvent("onHide", [this._overlay]);
		}
		
		return this;
	},
	
	toggleShowHide: function() {
		if (this._visible)
			this.hide();
		else
			this.show();
		
		return this;
	},
	
	isVisible: function() {
		return this._visible;
	},
	
	destroy: function() {
		if (this._visible)
			Window.removeEvent("resize", this._bound.updateBounds);
		
		this._overlay.remove();
		
		this.fireEvent("onDestroy");
	},
	
	_updateBounds: function() {
		if (this._visible) {
			var pageCoords = App.getCoordinates();
			
			this._overlay.setStyles({
				"left": "0px",
				"top": "0px",
				"width": pageCoords.width + "px",
				"height": pageCoords.height + "px"
			});
		}
		
		return this;
	}
});
Overlay.implement(new Options, new Events);

/**
 * Class: ModalBox
 */
var ModalBox = new Class({
	options: {
		containerClass: "tie-modalBox",
		zIndex: 10000,
		showCenter: true,
		centerOnScroll: false,
		
		canHide: function() {
			return true;
		},
		
		onBeforeShow: Class.empty,
		onShow: function(self) {
			self.container.setStyle("visibility", "visible");
		},
		onHide: function(self) {
			self.container.setStyle("visibility", "hidden");
		},
		onDestroy: Class.empty
	},
	
	initialize: function(id, options) {
		this.setOptions(options);
		this.id = id;
		
		this._build();
	},
	
	_build: function() {
		this.container = $(this.id);
		if (this.options.containerClass)
			this.container.addClass(this.options.containerClass);
		if (this.options.zIndex)
			this.container.setStyle("z-index", this.options.zIndex);
		
		if (this.options.showCenter) {
			this._bound = {
				centerDialog: this._centerDialog.bind(this)
			};
			
			this._moveFx = this._getMoveFx();
		}
		
		this._visible = this.container.getStyle("visibility") != "hidden";
	},
	
	show: function() {
		if (!this._visible) {
			this.fireEvent("onBeforeShow", [this]);
			
			this._visible = true;
			
			if (this.options.showCenter) {
				var centerPos = this._getCenterPosition();
				this.setPosition(centerPos.left, centerPos.top);
				
				Window.addEvent("resize", this._bound.centerDialog);
				if (this.options.centerOnScroll)
					Window.addEvent("scroll", this._bound.centerDialog);
			}
			
			this.updateContent();
			
			this._overlay = (new Overlay({
				ownerElement: this.container,
				
				onShow: function(overlay) {
					overlay.setOpacity(0);
					
					overlay.setStyle("display", "");
					
					overlay.effect("opacity", {"duration": 200}).start(0, 0.6).chain(function() {
						this.fireEvent("onShow", [this]);
					}.bind(this));
				}.bind(this)
			})).show();
		}
		
		return this;
	},
	
	hide: function() {
		if (this._visible && this.options.canHide()) {
			this._visible = false;
			
			if (this.options.showCenter) {
				Window.removeEvent("resize", this._bound.centerDialog);
				if (this.options.centerOnScroll)
					Window.removeEvent("scroll", this._bound.centerDialog);
			}
			
			this.fireEvent("onHide", [this]);
			
			this._overlay.destroy();
			
			this.setPosition(0, 0);
		}
		
		return this;
	},
	
	toggleShowHide: function() {
		if (this._visible)
			this.hide();
		else
			this.show();
			
		return this;
	},
	
	isVisible: function() {
		return this._visible;
	},
	
	destroy: function() {
		if (this._visible) {
			if (this.options.showCenter) {
				Window.removeEvent("resize", this._bound.centerDialog);
				if (this.options.centerOnScroll)
					Window.removeEvent("scroll", this._bound.centerDialog);
			}
			
			this._overlay.destroy();
			
			this.setPosition(0, 0);
		}
		
		this.fireEvent("onDestroy");
	},
	
	updateContent: function() {
		return this;
	},
	
	setPosition: function(left, top) {
		if ($defined(left))
			this.container.setStyle("left", left + "px");
		if ($defined(top))
			this.container.setStyle("top", top + "px");
		
		return this;
	},
	
	_getMoveFx: function() {
		return this.container.effects({"duration": 300, "wait": false});
	},
	
	_getCenterPosition: function() {
		var pageCoords = App.getCoordinates();
		var coords = this.container.getCoordinates();
		
		return {
			"left": pageCoords.width > coords.width ?
			        pageCoords.left + (pageCoords.width - coords.width) / 2 :
			        pageCoords.right - coords.width,
			"top": Math.min(pageCoords.bottom - coords.height,
			                Math.max(
			                  0,
			                  Window.getScrollTop() + (Window.getHeight() - coords.height) / 2
			                ))
		};
	},
	
	_centerDialog: function() {
		if (this._visible) {
			var centerPos = this._getCenterPosition();
			
			if (this._moveFx)
				this._moveFx.start({"left": centerPos.left, "top": centerPos.top});
			else
				this.setPosition(centerPos.left, centerPos.top);
		}
		
		return this;
	}
});
ModalBox.implement(new Options, new Events);

/**
 * Class: ContactForm
 */
var ContactForm = ModalBox.extend({
	options: {
		onShow: function(self) {
			self.container.setStyle("visibility", "visible");
			
			$E("#cf-firstname", self.container).focus();
		}
	},
	
	initialize: function(id, options) {
		this.setOptions(options);
		
		this.parent(id);
	},
	
	_build: function() {
		this.parent();
		
		$E("#cf-submit", this.container).addEvent("click", this.submit.bind(this));
		$E("#cf-cancel", this.container).addEvent("click", this.hide.bind(this));
	},
	
	updateContent: function() {
		this.parent();
		
		$$("#" + this.id + " p.field input", "#" + this.id + " p.field textarea").each(function(input) {
			input.value = "";
		});
	},
	
	submit: function() {
		/* Do something in here to update user-inputs to server.
		 * Such as:
		 * new Ajax("http://My-TIEweb.TIEglobal.com/docs/CRMNewQuestion_en.asp", {
		 *   data: $("cf-contact"),
		 *   onComplete: function(response) {
		 *     ...
		 *   }
		 * }).request();
		 */
		
		this.hide();
	}
});