/*
 * Dropdown menus
 */

var DropDownMenu = Class.create({

	initialize: function(dom_header, dom_content) {

		this.dom_header = $(dom_header);
		this.dom_content = $(dom_content);

		this.bound_click_header = this.click_header.bindAsEventListener(this);
		this.dom_header.observe("click", this.bound_click_header);

		this.bound_mouseover_header = this.mouseover_header.bindAsEventListener(this);
		this.dom_header.observe("mouseover", this.bound_mouseover_header);

		this.bound_mouseout_header = this.mouseout_header.bindAsEventListener(this);
		this.dom_header.observe("mouseout", this.bound_mouseout_header);

		this.bound_click_content = this.click_content.bindAsEventListener(this);
		this.dom_content.observe("click", this.bound_click_content);

		this.bound_mouseover_content = this.mouseover_content.bindAsEventListener(this);
		this.dom_content.observe("mouseover", this.bound_mouseover_content);

		this.bound_mouseout_content = this.mouseout_content.bindAsEventListener(this);
		this.dom_content.observe("mouseout", this.bound_mouseout_content);

		this.initialize_for_all();
	},


	initialize_for_all: function() {
		if (!DropDownMenu.initialized_for_all) {
			DropDownMenu.instances = [];
			DropDownMenu.click_document = function(e) {
				this.hide_all_instances();
			}
			DropDownMenu.hide_all_instances = function() {
				this.instances.each(function(instance) {
					instance.deactivate();
				});
			},
			DropDownMenu.bound_click_document = DropDownMenu.click_document.bindAsEventListener(DropDownMenu);
			Event.observe(document, "click", DropDownMenu.bound_click_document);
			DropDownMenu.initialized_for_all = true;
		}
		DropDownMenu.instances[DropDownMenu.instances.length] = this;
	},

	mouseover_header: function(e) {
		this.activate();
		return(false);
	},

	mouseout_header: function(e) {
		this.start_deactivate_timer();
		return(false);
	},

	click_header: function(e) {
		var was_visible = this.dom_content.visible();
		DropDownMenu.hide_all_instances();
		if (!was_visible) {
			this.activate();
		}
		Event.stop(e);
		return(false);
	},

	click_content: function(e) {
		var el = Event.element(e);
		var tag = el.tagName;
		var type = el.type;
		if (tag == "A" || (tag == "INPUT" && (type == "button" || type == "submit")) || tag == "BUTTON" || tag == "SUBMIT") {
			// Do nothing - event will bubble up and collapse all dropdowns
		}
		else {
			Event.stop(e);
		}
	},

	mouseover_content: function(e) {
		this.activate();
		return(false);
	},

	mouseout_content: function(e) {
		this.start_deactivate_timer();
		return(false);
	},

	activate: function() {
		this.cancel_deactivate_timer();
		DropDownMenu.hide_all_instances();
		this.dom_content.show();
		this.dom_header.addClassName("active");
	},

	deactivate: function() {
		this.cancel_deactivate_timer();
		this.dom_content.hide();
		this.dom_header.removeClassName("active");
	},

	start_deactivate_timer: function() {
		this.hide_timer = setTimeout(function() {
			this.deactivate();
		}.bind(this), 120);
	},

	cancel_deactivate_timer: function() {
		if (this["hide_timer"]) {
			clearTimeout(this.hide_timer);
			this.hide_timer = undefined;
		}
	}

});

var BoolRater = Class.create({

	initialize: function(rater_url, dom_rater, authenticity_token) {

		this.rater_url = rater_url;
		this.authenticity_token = authenticity_token;

		this.dom_rater = $(dom_rater);
		this.dom_in = this.dom_rater.down("a.in");
		this.dom_middle = this.dom_rater.down("strong.middle");
		this.dom_out = this.dom_rater.down("a.out");

		this.bound_click = this.click.bindAsEventListener(this);

		Element.observe(this.dom_in, 'click', this.bound_click);
		Element.observe(this.dom_out, 'click', this.bound_click);

	},

	click: function(e) {
		var link = Event.element(e);
		if (link.tagName != "A") return;

		var rate;
		if (link.hasClassName("active")) {
			rate = 0;
		}
		else if (link.hasClassName("in")) {
			rate = 1;
		}
		else if (link.hasClassName("out")) {
			rate = -1;
		}

		new Ajax.Request(this.rater_url + "/rate", {
			method: "post",
			parameters: {rate: rate, dom_id: this.dom_rater.id, authenticity_token: this.authenticity_token},
			onSuccess: this.rated_ok.bind(this),
			onFailure: function() { alert('Failed to save your vote.  Please try again later.') }
		});
		Event.stop(e);
		return(false);
	},

	rated_ok: function(transport) {
		/* Stop Observing */
	}

});

var FullRater = Class.create({

	initialize: function(rater_url, dom_rater, authenticity_token) {

		this.rater_url = rater_url;
		this.authenticity_token = authenticity_token;

		this.dom_rater = $(dom_rater);
		this.dom_rate_links = this.dom_rater.select("span.rates > a");

		/* Assign each rate link it's rate value as well as event observers */
		this.bound_hover_on = this.hover_on.bindAsEventListener(this);
		this.bound_hover_off = this.hover_off.bindAsEventListener(this);
		this.bound_click = this.click.bindAsEventListener(this);
		for (var i = 0; i < this.dom_rate_links.length; i++) {
			var link = this.dom_rate_links[i];
			link.rate = i + 1;
			Element.observe(link, 'mouseover', this.bound_hover_on);
			Element.observe(link, 'mouseout', this.bound_hover_off);
			Element.observe(link, 'click', this.bound_click);
		}
	},

	hover_on: function(e) {
		var link = Event.element(e);
		if (link.tagName != "A") return;
		return false;
	},

	hover_off: function(e) {
		return false;
	},

	click: function(e) {
		var link = Event.element(e);
		if (link.tagName != "A") return;
		new Ajax.Request(this.rater_url + "/rate", {
			method: "post",
			parameters: {rate: link.rate, authenticity_token: this.authenticity_token},
			onSuccess: this.rated_ok.bind(this),
			onFailure: function() { alert('Failed to save your rate.  Please try again later.') }
		});
		Event.stop(e);
		return(false);
	},

	rated_ok: function(transport) {
		var json = eval('(' + transport.responseText + ')');
		this.dom_rater.down("span.rates").remove();
		this.dom_rater.down("span.average").update(json.average);
		this.dom_rater.down("span.word").update("RATING:");
		this.dom_rater.down("span.average").show();
	}

});

/*
 * CollectionMembership manager
 */
var CollectionMembership = Class.create({

	/* Takes variable number arguments.  Any others past the ones clearly
	 * seen below are expected to be link ids to monitor
	 */
	initialize: function(clothing_item_id, collection_id, existing_collection_membership_id, authenticity_token) {

		/* Init */
		this.clothing_item_id = clothing_item_id;
		this.collection_id = collection_id;
		this.collection_membership_id = existing_collection_membership_id;
		this.authenticity_token = authenticity_token;
		this.bound_click = this.click.bindAsEventListener(this);

		/* Init links */
		this.links = [];
		for (var i=4; i < arguments.length; i++) {
			this.add_link(arguments[i]);
		}

	},

	click: function(e) {
		Event.stop(e);
		
		/*
		 * Initiate AJAX call
		 */
		if (this.collection_membership_id) {
			// Remove
			new Ajax.Request(("/collection_memberships/" + this.collection_membership_id),
				{
					method: "post",
					parameters: {
						"_method":	"delete",
						"authenticity_token":	this.authenticity_token
					},
					onSuccess: this.ajax_destroy_cb_ok.bind(this),
					onFailure: this.ajax_destroy_cb_notok.bind(this)
				}
			);
		}
		else {
			// Create
			new Ajax.Request("/collection_memberships",
				{
					method: "post",
					parameters: {
						"collection_membership[collection_id]": this.collection_id,
						"collection_membership[clothing_item_id]": this.clothing_item_id,
						"authenticity_token":	this.authenticity_token
					},
					onSuccess: this.ajax_create_cb_ok.bind(this),
					onFailure: this.ajax_create_cb_notok.bind(this)
				}
			);
		}

		Event.element(e).blur();
	},

	ajax_destroy_cb_ok: function(transport) {
		this.collection_membership_id = undefined;
		this.redraw();
	},

	ajax_destroy_cb_notok: function(transport) {
		alert("Failed to remove the item.  Please try again later.");
	},

	ajax_create_cb_ok: function(transport) {
		var json = eval('(' + transport.responseText + ')');
		this.collection_membership_id = json.id;
		this.redraw();
	},

	ajax_create_cb_notok: function(transport) {
		alert("Failed to add the item.  Please try again later.");
	},

	redraw: function() {
		for (var i = 0; i < this.links.length; i++) {
			var link = this.links[i]
			if (this.collection_membership_id) {
				link.addClassName("active");
				// Specific handling based on link type
				if (link.id == "favlink") {
					link.update("remove from favorites");
				}
				else if (link.hasClassName("saveto")) {
					link.title = "remove this item from this collection";
				}
			}
			else {
				link.removeClassName("active");
				// Specific handling based on link type
				if (link.id == "favlink") {
					link.update("add to favorites");
				}
				else if (link.hasClassName("saveto")) {
					link.title = "add this item to this collection";
				}
			}
		}
	},

	/*
	 * Adds a link to the internal links array and sets up it's event observer
	 * Also sets up internal property of link .collection_membership
	 * finally redraws
	 */
	add_link: function(link) {
		var exists = false;
		link = $(link);
		if (!link) {
			return false;
		}
		for (var i = 0; i < this.links.length; i++) {
			if (this.links[i] == link) {
				exists = true;
				break;
			}
		}
		if (!exists) {
			this.links[this.links.length] = link;
			Event.observe(link, 'click', this.bound_click);
			link.collection_membership = this;
			this.redraw();
			return true;
		}
		else {
			return false;
		}
	}

});

var LookTagger = Class.create({

	initialize: function(look_id, popup_html, authenticity_token) {

		this.look_id = look_id;
		this.popup_html = popup_html;
		this.authenticity_token = authenticity_token;

		this.dom_image = $("main_look_image");
		this.dom_image.style.cursor = "crosshair";

		this.dom_left_div = $$("div.left")[0];

		this.start_observers();

		new Effect.Pulsate(this.dom_image, {
			pulses: 1,
			duration: 0.3
		});
	},

	destroy: function() {
		this.dom_image.style.cursor = "default";
		this.remove_popup();
		this.stop_observers();
	},

	start_observers: function() {
		this.bound_image_click = this.image_click.bindAsEventListener(this);
		this.dom_image.observe('click', this.bound_image_click);

		this.bound_close_click = this.close_click.bindAsEventListener(this);
	},

	stop_observers: function() {
		this.bound_close_click = undefined;

		this.dom_image.stopObserving('click', this.bound_image_click);
		this.bound_image_click = undefined;
	},

	close_click: function(e) {
		e.stop();
		this.remove_popup();
	},

	update_image_offset: function(e) {
		var temp = this.dom_image.cumulativeOffset();
		this.image_offset_x = temp[0];
		this.image_offset_y = temp[1];
	},

	image_click: function(e) {
		this.update_image_offset();
		var x = e.pointerX() - this.image_offset_x;
		var y = e.pointerY() - this.image_offset_y;
		this.show_popup(x, y);
	},

	show_popup: function(x, y) {
		var popup = $("ClothingItemTagBox");
		if (popup) {
			new Effect.Pulsate("ClothingItemTagBox", {pulses: 2, duration: 0.6});
		}
		else {
			this.dom_left_div.insert(this.popup_html, {position: "bottom"});
			popup = $("ClothingItemTagBox");
			new Effect.Appear(popup, {duration: 0.4});
			popup.down("a.close").observe('click', this.bound_close_click);
		}

		popup.down("input#look_tag_x").value = x;
		popup.down("input#look_tag_y").value = y;
	},

	remove_popup: function() {
		var popup = $("ClothingItemTagBox");
		if (popup) {
			new Effect.Fade(popup, {
				duration: 0.4,
				afterFinish: function(e) {popup.remove();}
			});
		}
		else {
			return false;
		}
	},

	tagging_successful: function() {
		this.remove_popup();
		this.reload_tagged_clothing_items();
	},

	reload_tagged_clothing_items: function() {
		new Ajax.Request('/looks/' + this.look_id + '/tagged_clothing_items', {
			method: "get"
		});
	},

	tagging_unsuccessful: function(errors) {
		alert("Error saving item info: " + errors);
	}

});

var CropManager = Class.create({

	initialize: function(current_id) {
		this.current_id = current_id;
		this.dom_large_image = $("image_large");
		this.cropper = undefined;
		this.bound_cropper_end_cb = this.cropper_end_cb.bind(this);
		this.attach_cropper();
	},


	//Attaches/resets the image cropper
	attach_cropper: function() {

		this.remove_cropper();

		/* Set cropper_options */
		var cropper_options;
		if ($("crop_attributes_" + this.current_id + '_x1' ).value != '') {
			cropper_options = {
				onEndCrop: this.bound_cropper_end_cb,
				displayOnInit: true,
				onloadCoords: {
					x1: $( "crop_attributes_" + this.current_id + '_x1' ).value,
					y1: $( "crop_attributes_" + this.current_id + '_y1' ).value,
					x2: $( "crop_attributes_" + this.current_id + '_x2' ).value,
					y2: $( "crop_attributes_" + this.current_id + '_y2' ).value
				}
			};
		}
		else {
			cropper_options = {
				onEndCrop: this.bound_cropper_end_cb
			};
		}

		this.cropper = new Cropper.Img(this.dom_large_image, cropper_options);

	},


	//Sets the image within the element & attaches/resets the image cropper
	set_image: function(id) {
		this.current_id = id;
		var preloaded_image = $("preloadImage_" + id);
		this.dom_large_image.src = preloaded_image.src;
		this.attach_cropper();
	},

	// Removes the cropper (if there is one)
	remove_cropper: function() {
		if (this.cropper) {
			this.cropper.remove();
			this.cropper = undefined;
		}
	},

	//Resets the cropper and clears stored coords
	reset_cropper: function() {
	  $( "crop_attributes_" + this.current_id + '_x1' ).value = '';
	  $( "crop_attributes_" + this.current_id + '_y1' ).value = '';
	  $( "crop_attributes_" + this.current_id + '_x2' ).value = '';
	  $( "crop_attributes_" + this.current_id + '_y2' ).value = '';
	  this.attach_cropper();
	},

	// Callback function
	cropper_end_cb: function (coords, dimensions) {
	  if (dimensions.width < 5 || dimensions.height < 5) {
		  this.reset_cropper();
	  }
	  else {
		  $( "crop_attributes_" + this.current_id + '_x1' ).value = coords.x1;
		  $( "crop_attributes_" + this.current_id + '_y1' ).value = coords.y1;
		  $( "crop_attributes_" + this.current_id + '_x2' ).value = coords.x2;
		  $( "crop_attributes_" + this.current_id + '_y2' ).value = coords.y2;
	  }
	}

});

var FieldHint = Class.create({
	initialize: function(field, hint) {

		this.dom_field = $(field);
		this.dom_form = $(this.dom_field.form);
		this.hint = hint;

		this.start_observing();
		this.possibly_set_hint();
	},

	start_observing: function() {

		this.bound_field_focus = this.field_focus.bindAsEventListener(this);
		this.dom_field.observe('focus', this.bound_field_focus);

		this.bound_field_blur = this.field_blur.bindAsEventListener(this);
		this.dom_field.observe('blur', this.bound_field_blur);

		this.bound_form_submit = this.form_submit.bindAsEventListener(this);
		this.dom_form.observe('submit', this.bound_form_submit);
	},

	field_focus: function(e) {
		this.possibly_erase_hint();
	},

	field_blur: function(e) {
		this.possibly_set_hint();
	},

	form_submit: function(e) {
		this.possibly_erase_hint();
	},

	possibly_erase_hint: function() {
		var v = $F(this.dom_field);
		if (v == this.hint) {
			this.dom_field.value = "";
			this.dom_field.removeClassName("hint");
		}
	},

	possibly_set_hint: function() {
		var v = $F(this.dom_field);
		if (v.match(/^\s*$/)) {
			this.dom_field.value = this.hint;
			this.dom_field.addClassName("hint");
		}
	}

});

/*
 * One-off global classless functions
 */

/* Takes a value and appends it to the given textbox's value
	Is smart and understands commas
 */
function addValue(value, elem) {
	elem = $(elem);
	var parts = $F(elem).strip().split(/\s*,\s*/);
	var i;
	var alreadythere = false;

	for (i=0; i<parts.length; i++) {
		if (parts[i].toLowerCase() == value.toLowerCase()) {
			alreadythere = true;
			break;
		}
	}

	if (!alreadythere) {
		if (value.toLowerCase().indexOf(parts[parts.length - 1].toLowerCase()) == 0) {
			parts[parts.length - 1] = value;
		}
		else {
			parts[parts.length] = value;
		}
		elem.value = parts.join(", ");
	}

	return false;
}

function popup(element, width, height) {
	element = $(element);
	var shadowbox_opts = {
		"displayNav":	false,
		"width":			width + 'px',
		"height":		height + 'px',
		"player":		"html",
		"content":		element.innerHTML
	};
	Shadowbox.open(shadowbox_opts);
}

function look_tag_color_click(e) {
	Event.stop(e);
	var link = Event.element(e);
	var hinput = $(link).previous("input[type='hidden']");
	if (hinput.value == "") {
		hinput.value = link.title;
		link.addClassName("selected");
	}
	else {
		hinput.value = "";
		link.removeClassName("selected");
	}
}

function redraw_look_darts(info) {
	var dart_width = 13;
	var dartboard = $("dartboard");
	var img = $("main_look_image");

	var offset_top = 0;
	var offset_left = 0;
	var img_width = img.getWidth();
	var parent_width = img.up("div.photo").getWidth();
	if (img_width < parent_width) {
		offset_left = Math.floor((parent_width - img_width) / 2);
	}

	dartboard.update("");
	info.each(function(tag_info) {
		var span = $("look_tag_" + tag_info.id);
		var color_class = span.down("a").className;
		var style_top = (offset_top + Math.floor(tag_info.y - (dart_width/2))) + "px";
		var style_left = (offset_left + Math.floor(tag_info.x - (dart_width/2))) + "px";
		var dart = new Element("a", {
			"href": tag_info.href,
			"title": tag_info.title,
			"id": "dart_" + tag_info.id,
			"class": "dart " + color_class,
			"style": "top: " + style_top + "; left: " + style_left + ";",
			"onmouseover": "look_highlight_tag(" + tag_info.id + ")"
		});
		dart.update("&nbsp;");
		dartboard.insert(dart, {position: "end"});
	});
}

function look_dartboard_show(dart_id) {
	var dartboard = $("dartboard");
	if (dartboard.hasClassName("firstPic")) {
		dartboard.show();
		dartboard.select("a.dart").each(function(dart) {
			if (dart_id && dart_id != dart.id) {
				dart.hide();
			}
			else {
				dart.show();
				if (dart_id) {
					look_highlight_dart(dart);
				}
			}
		});
	}
	else {
		look_dartboard_hide();
	}
}

function look_dartboard_hide() {
	$("dartboard").hide();
}

function look_tag_respect_category() {
	var category = $F("look_tag_category");
	var type_dropdown = $("look_tag_clothing_type_id");
	type_dropdown.length = 0;
	clothing_types.each(function(ct) {
		if (ct["category_" + category]) {
			var option = new Element("option", {value: ct.id}).update(ct.name);
			type_dropdown.insert(option);
		}
	});
}

function login_prompt() {
	if (confirm('Would you like to login or sign-up to use this feature ?')) {
		document.location = '/login';
	}
}

function update_event_top_look(url) {
	$("event_top_look").down("img").src = "/images/spinner1.gif";
	new Ajax.Request(url, {
		method: "get",
		onFailure: function() { alert('Failed to load look.  Please try again later.') }
	});
}

function outgoing_go(url) {
	document.location.href = "/out?url=" + encodeURIComponent(url);
	return(true);
}

function outgoing_witness(url) {
	var i = new Image();
	i.src = "/out?witness=1&url=" + encodeURIComponent(url);
	return(true);
}

function look_highlight_dart(dart) {
	new Effect.Pulsate(dart, {
		queue: { position: 'end', scope: 'look_tag_darts' },
		pulses: 2,
		duration: 1
	});
}

function look_highlight_tag(id) {
	var tag = $("look_tag_" + id);
	new Effect.Pulsate(tag, {
		queue: { position: 'end', scope: 'look_tag_darts' },
		pulses: 2,
		duration: 1
	});
}
