/*** Environment Settings ***/
Position.includeScrollOffsets = true;
Prototype.Browser.GeckoMac = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Macintosh') > -1
Prototype.Browser.IE6 = (navigator.appVersion != null && navigator.appVersion.indexOf("MSIE 6.0") != -1);

/**
 * STATICS
**/
var STATICS = {
	loader_show_delay: 0.3,
	ajax_disabled: true
}


/**
 * module Locator
**/
var Locator = {
	
	last_clicked: null,
	
	prev_path: null,
	
	locate: function (clicker, new_url) {
		Locator.last_clicked = clicker;
		
		var stdpath = window.location.toString().gsub(/https?:\/\/.+?(?=\/)/, "").split("/#")[0];
		
		if (new_url.include(stdpath)) new_url = new_url.sub(stdpath, "");
		
		Locator.prev_path = new_url;
		
		// SWFAddress.setValue(new_url);
	},
	
	redirect_if_necessary: function () {
		if (window.location.toString().include("/#")) window.location = window.location.toString().sub("/#", "");
	},
	
	handle_change: function (event) {
		if (Locator.prev_path == event.path) return;
		if (!Locator.last_clicked || !Locator.last_clicked.goto_url) return;
		Locator.last_clicked.goto_url(window.location.toString().gsub(/https?:\/\/.+?(?=\/)/, "").split("/#")[0] + event.path);
	},
	
	listen_to_swf_address: function () {
		// SWFAddress.addEventListener(SWFAddressEvent.CHANGE, Locator.handle_change);
	}
	
}
Locator.redirect_if_necessary();
Locator.listen_to_swf_address();


/**
 * class Column
**/
var Column = Class.create({
	
	initialize: function (element) {
		Column.instances.push(this);
		
		this._element = $(element);
		this._link = this._element.down("a");
		
		if (Prototype.Browser.IE6) this._apply_ie_fix();
		
		this._activate_rollover();
	},
	
	_apply_ie_fix: function () {
		this._element.addClassName("column_ie");
		var bg = new Element("div", {"class": "column_bg_ie"});
		bg.update("&nbsp;");
		this._element.insert(bg);
	},
	
	_activate_rollover: function () {
		if (!this._link) return;
		
		if (this._link.readAttribute("href") != "#") {
			this._link.observe("mouseover", this._on_mouseover.bindAsEventListener(this));
			this._link.observe("mouseout", this._on_mouseout.bindAsEventListener(this));
		} else {
			this._link.observe("click", function (event) { event.stop() });
		}
	},
	
	_on_mouseover: function (event) {
		this._element.addClassName("column_hover");
		if (!this._element.hasClassName("column_active")) this._element.removeClassName("column_unhover");
	},
	_on_mouseout: function (event) {
		this._element.removeClassName("column_hover");
		if (!this._element.hasClassName("column_active")) this._element.addClassName("column_unhover");
	}
	
});
Column.instances = [];
Column.instaniate_all = function (root) {
	$(root).childElements().each(function (element) {
		if (element.hasClassName("top_nav_item")) new Column(element);
	});
}


/**
 * class BackgroundRotator
**/
var BackgroundRotator = Class.create({
	
	initialize: function (element) {
		BackgroundRotator.instances.push(this);
		
		this.element = $(element);
		this.images = this.element.select(".background_image");
		this._count = this.images.length;
		this._animating = false;
		
		if (this.images.length > 1) {
			var image_urls = this.images.map(function (image) {
				var src = image.getStyle("background-image");
				src = src.gsub(/(url|\(["']?|["']?\)|;)/, "");
				return src;
			});
			new ImagePreLoader(
				image_urls, {
				on_images_loaded: this._on_images_loaded.bind(this)
			});
		}
	},
	
	start_rotation: function (wait) {
		if (this.images.length < 2) return; // too few images to rotate
		
		if (wait && wait > 0) this._start_rotation_interval = this.start_rotation.bind(this).delay(wait);
		else this._next_image();
	},
	
	_on_images_loaded: function () {
		this._last_fade_finish = this._paused_at = new Date().getTime();
		
		Event.observe(window, "scroll", this._on_window_scroll.bind(this));
		Event.observe(window, "blur", this._on_window_blur.bind(this));
		Event.observe(window, "focus", this._on_window_focus.bind(this));
		
		var first_image = this.images.splice(Math.floor(Math.random() * this.images.length), 1)[0];
		this.images.unshift(first_image);
		
		this._stack_images();
		
		this.element.show();
		
		this._rotation_delay = BackgroundRotator.rotation_delay;
		this._scroll_delay = BackgroundRotator.scroll_delay;
		this.start_rotation(this._rotation_delay);
	},
	
	_stack_images: function (image_set) {
		this.images.reverse(false).each(function (element, index) {
			element.setStyle({ zIndex: (index + 1), border: '0 none' })
		});
	},
	
	_next_image: function () {
		if (this._animating) return;
		this._animating = true;
		
		top_image = this.images.first();
		
		this._effect = new Effect.Opacity(top_image, {
			duration: (top_image.getOpacity() / 1.0) * BackgroundRotator.fade_duration,
			fps: 10,
			from: top_image.getOpacity(), to: 0.0,
			afterFinish: this._complete_transition.bind(this)
		});
	},
	
	_complete_transition: function (effect) {
		top_image = this.images.splice(0, 1)[0];
		this.images.push(top_image);
		this._stack_images();
		top_image.setStyle({opacity: 1.0});
		
		this._effect = null;
		this._animating = false;
		this._last_fade_finish = new Date().getTime();
		
		if (!this._paused) this._next_image_interval = this._next_image.bind(this).delay(this._rotation_delay);
	},
	
	_on_window_scroll: function () {
		this.pause("window_scroll");
		clearInterval(this._on_window_scroll_finish_interval);
		this._on_window_scroll_finish_interval = this._on_window_scroll_finish.bind(this).delay(this._scroll_delay);
	},
	
	_on_window_blur: function () {
		this.pause("window_blur");
	},
	
	_on_window_focus: function () {
		this.play("window_blur");
	},
	
	_on_window_scroll_finish: function () {
		this.play("window_scroll");
	},
	
	play: function (caller_id) {
		if (!this._pause_requests) this._pause_requests = new Hash();
		this._pause_requests.unset(caller_id);
		
		if (this._pause_requests.keys().length == 0) {
			this._paused = false;
			
			if (this._effect) { // we can finish the effect right away and carry on
				this.start_rotation(0);
			} else { // we should pick up the rotation delay where we left off
				var delay_ms_completed = (this._paused_at - this._last_fade_finish) / 1000;
				this.start_rotation(this._rotation_delay - delay_ms_completed);
			}
		}
	},
	
	pause: function (caller_id) {
		if (!this._pause_requests) this._pause_requests = new Hash();
		this._pause_requests.set(caller_id, true);
		if (!this._paused) {
			if (this._effect) this._effect.cancel();
			this._animating = false;
			this._paused = true;
			this._paused_at = new Date().getTime();
			clearInterval(this._start_rotation_interval);
			clearInterval(this._next_image_interval);
		}
	}
	
});
BackgroundRotator.fade_duration = 6; // 6
BackgroundRotator.rotation_delay = 8; // 8
BackgroundRotator.fps = 12;
BackgroundRotator.scroll_delay = 0.5;
BackgroundRotator.instances = [];
BackgroundRotator.instaniate_all = function (root) {
	new BackgroundRotator(root);
}
BackgroundRotator.play = function (caller_id) {
	BackgroundRotator.instances.invoke("play", caller_id);
}
BackgroundRotator.pause = function (caller_id) {
	BackgroundRotator.instances.invoke("pause", caller_id);
}


/**
 * class BackgroundImage
**/
var BackgroundImage = Class.create({
	
	initialize: function (element, rotator) {
		BackgroundImage.instances.push(this);
		
		this._element = $(element);
		this._rotator = rotator;
	}
	
});
BackgroundImage.instances = [];


/**
 * class SubNav
**/
var SubNav = Class.create({
	
	initialize: function (element) {
		this._element = $(element);
		this._items = [];
		this._selected_item = null;
		
		this._element.select(".sub_nav_item").each(function (item) {
			var sub_nav_item = new SubNavItem(item, this);
			this._items.push(sub_nav_item);
			if (sub_nav_item.selected()) this._selected_item = sub_nav_item;
		}.bind(this));
		
		this._create_response_container();
		
		this.activate();
	},
	
	activate: function () {
		this._active = true;
		this._items.invoke("activate");
	},
	
	deactivate: function () {
		this.active = false;
		this._items.invoke("deactivate");
	},
	
	show_loader: function (delay) {
		if (delay) {
			this._loader_show_interval = this.show_loader.bind(this).delay(delay);
			return;
		}
		
		this._loader_show_interval = null;
		
		if (!this._load_message) {
			this._load_message = new Element("div", {"class": "loading"});
			var message = new Element("span", {"class": "message"});
			message.update("Loading...");
			this._load_message.insert(message);
			this._response_container.insert(this._load_message);
		}
		
		this._load_message.show();
		this._load_message.setStyle({ height: this._load_message.up().getHeight() + "px" });
	},
	
	hide_loader: function () {
		if (this._loader_show_interval) clearInterval(this._loader_show_interval);
		if (this._load_message) this._load_message.hide();
	},
	
	goto_url: function (url, sub_nav_item) {
		if (!sub_nav_item) sub_nav_item = this._items.find(function (item) { return item.url().include(url) });
		
		if (this._selected_item) this._selected_item.deselect();
		sub_nav_item.select();
		this._selected_item = sub_nav_item;
		
		this._create_response_container();
		
		this.show_loader(STATICS.loader_show_delay);
		
		new Ajax.Request(
			url, {
			onComplete: this._on_request_complete.bind(this),
			method: 'get'
		});
		
		// Locator.locate(this, url);
	},
	
	reveal_response: function () {
		if (SubNav.animation) {
			/* TODO */
		} else {
			this._on_response_revealed();
		}
	},
	
	hide_response: function () {
		if (SubNav.animation) {
			/* TODO */
		} else {
			this._response_container.hide();
			this._on_response_hidden();
		}
	},
	
	_create_response_container: function () {
		if (this._response_container) return;
		
		this._response_container = new Element("div", { "class": "response_container" });
		this._response_container_inner = new Element("div", {"class": "response_container_inner"});
		this._response_container.insert(this._response_container_inner);
		this._element.insert({ after: this._response_container });
		
		this._put_siblings_in_container();
	},
	
	_put_siblings_in_container: function () {
		this._response_container.nextSiblings().each(function (element) {
			element.remove();
			this._response_container_inner.insert(element);
		}.bind(this));
	},
	
	_on_request_complete: function (response) {
		this._prev_response_inner = this._response_container_inner;
		
		this._response_container_inner = new Element("div", {"class": "response_container_inner"});
		
		var temp_element = new Element("div");
		temp_element.update(response.responseText.gsub(/[\s\S]*<body>([\s\S]*)<\/body>[\s\S]*/, '#{1}').stripScripts());
		var me_in_temp = temp_element.childElements()[1].childElements()[2].childElements().find(function (element) {
			return element.identify() == this._element.identify();
		}.bind(this));
		
		var new_elements = me_in_temp.nextSiblings();
		
		new_elements.each(function (element) {
			this._response_container_inner.insert(element.remove());
		}.bind(this));
		
		
		var images = this._response_container_inner.select("img");
		
		if (images.length > 0) {
			this._preload_images.bind(this, images).defer();
		} else {
			this._on_content_loaded();
		}
	},
	
	_preload_images: function (images) {
		new ImagePreLoader(
			images, {
			on_images_loaded: this._on_content_loaded.bind(this)
		});
	},
	
	_on_content_loaded: function () {
		this._response_container.insert(this._response_container_inner);
		if (this._prev_response_inner) this._prev_response_inner.remove();
		
		SubNav.instantiate_all(this._response_container_inner);
		Bundle.instantiate_all(this._response_container_inner);
		
		this.hide_loader();
		this.reveal_response();
	},
	
	_on_response_revealed: function () {
		
	},
	
	_on_response_hidden: function () {
		
	}
	
});
SubNav.instances = [];
SubNav.instantiate_all = function (root) {
	if (STATICS.ajax_disabled) return;
	
	$(root).childElements().each(function (element) {
		if (element.hasClassName("sub_nav")) new SubNav(element);
	});
}
SubNav.animation = false;


/**
 * class SubNavItem
**/
var SubNavItem = Class.create({
	
	initialize: function (element, controller) {
		this._element = $(element);
		this._controller = controller;
	},
	
	id: function () {
		return this._element.identify();
	},
	
	url: function () {
		return this._element.readAttribute("href");
	},
	
	width: function () {
		return this._element.getWidth();
	},
	
	height: function () {
		return this._element.getHeight();
	},
	
	activate: function () {
		if (this.active()) return;
		
		if (!this._observing) {
			this._element.observe("click", this._on_click.bindAsEventListener(this));
			this._observing = true;
		}
		
		this._active = true;
	},
	
	deactivate: function () {
		if (!this.active()) return;
		this._active = false;
	},
	
	active: function () {
		return this._active;
	},
	
	select: function () {
		this._element.addClassName("active");
	},
	
	deselect: function () {
		this._element.removeClassName("active");
	},
	
	selected: function () {
		return this._element.hasClassName("active");
	},
	
	_on_click: function (event) {
		event.stop();
		if (this._element.hasClassName("disabled")) return;
		if (this.selected() || !this.active()) return;
		this._controller.goto_url(this.url(), this);
	}
	
});
SubNavItem.instances = [];


/**
 * class Bundle
**/


var Bundle = Class.create({
	
	initialize: function (element) {
		this._element = $(element);
		this._link = this._element.down("a");
		this._close_button = this._element.down(".close_button");
		Bundle.instances.push(this);
		//if (!this._link.hasClassName("overview_active")) this.activate();
	},
	
	id: function () {
		return this._element.id;
	},
	
	activate: function () {
		this._link.removeClassName("overview_active");
		
		if (!this._observing) {
			this._link.observe("click", this.open.bindAsEventListener(this));
			this._close_button.observe("click", this.close.bindAsEventListener(this));
			this._observing = true;
		}
		
		this._link_disabled = false;
	},
	
	deactivate: function () {
		this._link.addClassName("overview_active");
		
		this._link_disabled = true;
	},
	
	url: function () {
		if (!this._url) this._url = this._link.readAttribute("href");
		return this._url;
	},
	
	open: function (event) {
		event.stop();
		
		if (this._link_disabled) return;
		
		if (Bundle.animation) BackgroundRotator.pause(this.id());
		
		this.hide_quicktime();
		
		this.deactivate();
		
		if (this._response_container) this.reveal_response();
		else this.request();
		
		// Locator.locate(this, this.url());
	},
	
	close: function (event) {
		if (event) event.stop();
		
		if (!this._link_disabled) return;
		
		if (Bundle.animation) BackgroundRotator.pause(this.id());
		
		this.hide_quicktime();
		
		this._close_button.observe("click", function (event) { event.stop() });
		
		this.hide_close_button();
		
		// Locator.locate(this._close_button.readAttribute("href"));
	},
	
	request: function () {
		this.show_loader(STATICS.loader_show_delay);
		
		new Ajax.Request(
			this.url(), {
			evalJS: false,
			onComplete: this._on_request_complete.bind(this),
			method: 'get'
		});
	},
	
	show_loader: function (delay) {
		if (delay) {
			this._loader_show_interval = this.show_loader.bind(this).delay(delay);
			return;
		}
		
		this._loader_show_interval = null;
		
		if (!this._load_message) {
			this._load_message = new Element("div", {"class": "loading"});
			var message = new Element("span", {"class": "message"});
			message.update("Loading...");
			this._load_message.insert(message);
			this._element.insert(this._load_message);
			this._load_message.setStyle({
				height: this._load_message.up().getHeight() + "px"
			});
		}
		this._load_message.show();
	},
	
	hide_loader: function () {
		if (this._loader_show_interval) clearInterval(this._loader_show_interval);
		if (this._load_message) this._load_message.hide();
	},
	
	reveal_response: function () {
		if (Bundle.animation) {
			new Effect.SlideDown(
				this._response_container, {
				duration: Bundle.appear_duration,
				afterFinish: this._on_response_revealed.bind(this)
			});
		} else {
			this._response_container.show();
			this._on_response_revealed();
		}
	},
	
	hide_response: function () {
		if (Bundle.animation) {
			new Effect.SlideUp(
				this._response_container, {
				duration: Bundle.appear_duration,
				afterFinish: this._on_response_hidden.bind(this)
			});
		} else {
			this._response_container.hide();
			this._on_response_hidden();
		}
	},
	
	reveal_close_button: function () {
		if (Bundle.animation) {
			new Effect.SlideDown(
				this._close_button.up(), {
					duration: Bundle.close_button_appear_duration,
					afterFinish: this._on_close_button_revealed.bind(this)
			});
		} else {
			this._close_button.up().show();
			this._on_close_button_revealed();
		}
	},
	
	hide_close_button: function () {
		if (Bundle.animation) {
			new Effect.SlideUp(
				this._close_button.up(), {
				duration: Bundle.close_button_appear_duration,
				afterFinish: this._on_close_button_hidden.bind(this)
			});
		} else {
			this._close_button.up().hide();
			this._on_close_button_hidden();
		}
	},
	
	show_quicktime: function () {
		if (!this._response_container) return;
		this._response_container.select("object").each(function (element) { element.setStyle({ height: null }) });
	},
	
	hide_quicktime: function () {
		if (!this._response_container) return;
		this._response_container.select("object").each(function (element) { element.setStyle({ height: "0px" }) });
	},
	
	
	_on_request_complete: function (response) {
		// <div class="response_container">
		//   <div class="response_container_inner">
		//     ...response.responseText...
		
		this._response_container = new Element("div", { "class": "response_container" });
		this._response_container_inner = new Element("div", {"class": "response_container_inner"});
		this._response_container.insert(this._response_container_inner);
		
		var temp_element = new Element("div");
		temp_element.update(response.responseText.gsub(/[\s\S]*<body>([\s\S]*)<\/body>[\s\S]*/, '#{1}').stripScripts());
		
		var me_in_temp = temp_element.childElements()[1].childElements()[2].childElements().find(function (element) {
			return element.identify() == this.id();
		}.bind(this));
		
		var new_elements = me_in_temp.nextSiblings();
		
		new_elements.each(function (element) {
			this._response_container_inner.insert(element.remove());
		}.bind(this));
		
		this._element.insert({ after: this._response_container });
		this._response_container.hide();
		
		var images = this._response_container_inner.select("img");
		
		if (images.length > 0) {
			this._preload_images.bind(this, images).defer();
		} else {
			this._on_content_loaded();
		}
	},
	
	_preload_images: function (images) {
		new ImagePreLoader(
			images, {
			on_images_loaded: this._on_content_loaded.bind(this)
		});
	},
	
	_on_content_loaded: function () {
		SubNav.instantiate_all(this._response_container_inner);
		Bundle.instantiate_all(this._response_container_inner);
		
		this.hide_loader();
		this.reveal_response();
	},
	
	_on_response_revealed: function (effect) {
		this.reveal_close_button();
	},
	
	_on_response_hidden: function (effect) {
		this._on_closed();
	},
	
	_on_close_button_revealed: function (effect) {
		this._on_opened();
	},
	
	_on_close_button_hidden: function (effect) {
		this.hide_response();
	},
	
	_on_opened: function () {
		if (Bundle.animation) BackgroundRotator.play(this.id());
		this.show_quicktime();
	},
	
	_on_closed: function () {
		if (Bundle.animation) BackgroundRotator.play(this.id());
		this.activate();
	}
	
});
Bundle.instances = [];
Bundle.instantiate_all = function (root) {
	if (STATICS.ajax_disabled) return;
	
	$(root).childElements().each(function (element) {
		if (element.hasClassName("bundle")) new Bundle(element);
	});
}
Bundle.animation = true;
Bundle.appear_duration = 0.6;
Bundle.close_button_appear_duration = 0.2;


/**
 * class VideoPlayer
**/
var VideoPlayer = Class.create({
	
	initialize: function (container_id, player_id) {
		VideoPlayer.instances[container_id] = this;
		this._container_id = container_id;
		this._player_id = player_id;
	},
	
	activate: function () {
		this._element = $(this._player_id);
		this._element.addEventListener("onStateChange", "VideoPlayer.instances." + this._container_id + ".on_state_change");
	},
	
	on_state_change: function (state) {
		if (state == this._old_state) return;
		
		this._old_state = state;
		
		switch (state) {
		case -1: // unstarted
		case 5: // video cued
			break;
		case 1: // playing
		case 3: // buffering
			BackgroundRotator.pause(this._player_id);
			break;
		case 0: // ended
		case 2: // paused
			BackgroundRotator.play(this._player_id);
			break;
		};
	}
	
});
VideoPlayer.instances = {};
VideoPlayer.activate = function (container_id) {
	VideoPlayer.instances[container_id].activate();
}
var onYouTubePlayerReady = VideoPlayer.activate;
VideoPlayer.listen_for_quicktime = function () {
	// Since alpha rotation in Gecko causes loads problems on Mac, we'll just disable 
	// background rotation if we've a quicktime plugin present
	//
	// Also, qt_begin and qt_play events get fire before window.load, so need to re-send onload
	if (Prototype.Browser.GeckoMac) {
		Event.observe(document, "qt_begin", function () {
			Event.observe(window, "load", function () { BackgroundRotator.pause("quicktime") });
			BackgroundRotator.pause("quicktime");
		});
	} else {
		Event.observe(document, "qt_play", function () {
			Event.observe(window, "load", function () { BackgroundRotator.pause("quicktime") });
			BackgroundRotator.pause("quicktime");
		});
		Event.observe(document, "qt_pause", function () { BackgroundRotator.play("quicktime") });
		Event.observe(document, "qt_ended", function () { BackgroundRotator.play("quicktime") });
	}
}
VideoPlayer.listen_for_quicktime();

/**
 * ImagePreLoader
**/
var ImagePreLoader = Class.create({
	
	initialize: function (images, callbacks) {
		if (!images instanceof Array) images = [images];
		
		for (var event_name in callbacks) {
			this[event_name] = callbacks[event_name]
		}
		
		if (!Prototype.Browser.IE6) {
			this._count = images.length;
	
			images.map(function (image) {
				var img_loader = new Image();
				img_loader.onload = this._on_image_loaded.bind(this);
				img_loader.src = (image.readAttribute) ? image.readAttribute("src") : image;
			}.bind(this));
		} else {
			this.on_images_loaded();
		}
	},
	
	_on_image_loaded: function (image) {
		this._count--;
		if (this._count == 0) this.on_images_loaded();
	}
	
});


/**
 * function onload
**/
Event.observe(window, "load", function (event) {
	if (!Prototype.Browser.MobileSafari) {
		Column.instaniate_all("celluloid_top_nav_items");
		Bundle.instantiate_all("celluloid_content");
		SubNav.instantiate_all("celluloid_content");
		BackgroundRotator.instaniate_all("celluloid_background_images");
		
		Event.observe(document, "mousedown", function (event) {
			if (Event.element(event).nodeName.toLowerCase() == "img") event.stop();
		});
	}
	$("celluloid_footer").down().hide()
}.bindAsEventListener(this));
