$(document).ready(function() {
	var canRun = $('body').is('#photos') || $('body').is('#set');

	if (canRun) {
		window.EditPhoto = new $.EditPhoto().init();
	}
});

/** extend jquery */
$.fn.extend( {
	nodes : function(type, contains) {
		var children = [], valid;
		if (!this[0])
			return false;
		$(this[0].childNodes).each(function() {
			valid = true;
			if (type && this.nodeType !== type)
				valid *= false;
			if (contains && this.nodeValue && !this.nodeValue.match(contains))
				valid *= false;
			if (valid === true)
				children.push(this);
		});
		return $(children);
	}
});

/** object for faces manupulation */
$.Face = {
	/* find face */
	/* @param data - faces[] */
	find : function(data, imageInstanceId) {
		var position = null;
		$(data).each(function(i) {
			if (this.imageInstanceId === imageInstanceId)
				position = i;
		});
		return position;
	},
	/* replace face */
	// @param data - faces[], facebox -[]
	replace : function(data, facebox) {
		var faceid = this.find(data, facebox.imageInstanceId);
		if (faceid === null)
			return false;
		data[faceid] = facebox;
		return true;
	},
	// render face
	render : function(imageInstanceId) {
		var thumb = $('#inst-' + imageInstanceId + ' img.thumbnail');
		var face = window.faces[this.find(window.faces, imageInstanceId)];
		$('#inst-' + imageInstanceId + ' .facebox').remove();

		for ( var j = 0; j < face.faceboxes.length; j++) {
			var sizes = window.EditPhoto.getThumbnailSize(thumb, face.faceboxes[j], face.imageWidth);
			window.EditPhoto.setThumbnailPositionAndFacebox(imageInstanceId, face.imageMd5, face.faceboxes[j], sizes, face.imageOwnerUserId);
		}
		return face;
	},
	// render face names
	names : function(face) {
		var container = $('#inst-' + face.imageInstanceId).parents('.photo_container');
		$('.meta.name', container).remove();
		container.nodes(3, ',').remove();
		container.nodes(3, 'and').remove();

		var separators = [ "", " and ", " , " ];
		var separatorIndex = 0;
		for ( var j = 0; j < face.faceboxes.length; j++) {
			var facebox = face.faceboxes[j];
			var name = facebox.screenName || facebox.faceboxName.nameeScreenName;
			var faceboxUrl = '/photos/' + (facebox.nameeId || facebox.faceboxName.nameeUserId) + '/you';
			if (name) {
				container.find('.meta.byline').before('<li class="meta name"><a href="' + faceboxUrl + '" title="View photos that ' + name + ' appears in…">' + name + '</a></li>');
				if (separatorIndex > 0) {
					container.find('.meta.byline').before(separators[separatorIndex]);
				}
				separatorIndex = Math.min(2, separatorIndex + 1);
			}
		}
		return container;
	}
};

// obejct for edit photo
$.EditPhoto = function(o) {
	var global = this;
	var o = {
		modal : '#modal-edit_photo',
		modalClose : '#modal-edit_photo .close_modal, #modal-edit_photo .secondary a',
		modalclose : '#modal-delete_confirm',
		modalcloseClose : '#modal-delete_confirm .close_modal, #modal-delete_confirm .secondary a',
		modalname : '#modal-edit-photo-who_is_this',
		modalnameClose : '#modal-edit-photo-who_is_this .close_modal, #modal-edit-photo-who_is_this .secondary a',
		editbutton : '.function.edit',
		cache : {
			node : null,
			face : {},
			oldface : {}
		}
	};
	var DELETE_URL = '/edit-photo/confirm?faceboxId=__FACEBOX_ID__&amp;faceboxUuid=__FACEBOX_UUID__&amp;imageMD5=__IMAGE_MD5__&amp;imageInstanceId=__IMAGE_INSTANCE_ID__';
	var FACEBOX_HTML_TEMPLATE = '<div class="facebox" style="left: __LEFT__px; top: __TOP__px; width: __WIDTH__px; height: __HEIGHT__px;" title="__NAME__"><span></span></div>';
	var NAME_HTML_TEMPLATE = '<span class="name"><strong title="__NAME__">__NAME__</strong><a class="delete" href="' + DELETE_URL + '" title="Remove __NAME__ from this photo">[x]</a> </span> ';
	var NAME_LOCKED_HTML_TEMPLATE = '<span class="name"><strong title="__NAME__">__NAME__</strong></span> ';

	var UNKNOWN_HTML_TEMPLATE = '<span class="name"><strong title="Unknown Person">Unknown Person</strong> </span> ';
	var LOCKED_HTML_TEMPLATE = '<span class="name"><strong title="Private">Private</strong> </span> ';

	var META_TEMPLATE = '<em>In this photo: </em>';
	var namingData;

	/* init edit photo */
	this.init = function() {
		global.photoEvents();
		global.namedEvents();
		global.deleteEvents();
	};

	// close modal
	this.close = function() {
		$(this).parents('.modal').fadeOut(600, function() {
			$(this).remove();
			$('#overlay').hide();
		});
		$(o.modalname).remove();
		$(o.modalclose).remove();
		$('.templates').empty();

		if (o.cache.face != o.cache.oldface) {
			// global.update();
			window.location.reload();
		}
		delete o.cache.face;
		delete o.cache.oldface;

		return false;
	};

	this.setThumbnailPositionAndFacebox = function(imageInstanceId, imageMd5, facebox, sizes, selector, imageOwnerId) {

		if (facebox.locked) {

			if (facebox.named) {

				/*
				 * facebox is named - even though it is locked - we will still
				 * redirect to namee/me page
				 */
				var faceboxUrl = '/photos/' + facebox.nameeId + '/you';
				$(selector).append('<a class="facebox named locked" id="' + facebox.faceboxId + '" href="' + faceboxUrl + '" title="Private"><!--[if IE]><span></span><![endif]--></a>');
			} else {
				$(selector).append('<div class="facebox name locked" id="' + facebox.faceboxId + '" title="Unknown Person"><!--[if IE]><span></span><![endif]--></div>');
			}
		} else {

			if (facebox.named) {
				/*
				 * facebox is named, we will not show namig modal, we will
				 * redirect to namee/me page
				 */
				var faceboxUrl = '/photos/' + facebox.nameeId + '/you';
				$(selector).append('<a class="facebox named" id="' + facebox.faceboxId + '" href="' + faceboxUrl + '" title="' + facebox.screenName + '"><!--[if IE]><span></span><![endif]--></a>');
			} else {
				var faceboxUrl = '/edit/view?faceboxId=' + facebox.faceboxId + '&faceboxUuid=' + facebox.faceboxUuid + '&imageMD5=' + imageMd5 + '&imageInstanceId=' + imageInstanceId
						+ '&imageOwnerId=' + imageOwnerId;

				$(selector).append('<a class="facebox name" id="' + facebox.faceboxId + '" _href="' + faceboxUrl + '" title="Unknown Person"><!--[if IE]><span></span><![endif]--></a>');
			}
		}
		var faceboxDiv = $('#' + facebox.faceboxId);
		faceboxDiv.css(sizes);

	};

	this.getThumbnailSize = function(thumb, facebox, imageWidth) {
		var thumbWidth = thumb.width();
		var thumbOffsetX = parseInt((thumb.outerWidth(true) - thumbWidth) * 0.5, 10);
		var thumbOffsetY = parseInt((thumb.outerHeight(true) - thumb.height()) * 0.5, 10);
		var ratio = thumbWidth / imageWidth;
		var size = facebox.faceboxSize * ratio;

		return {
			'width' : Math.round(size) - 2,
			'height' : Math.round(size) - 2,
			'top' : Math.round(facebox.faceboxY * ratio) + 9,
			'left' : Math.round(facebox.faceboxX * ratio) + 9
		};
	};

	this.setThumbnailPositionAndFaceboxes = function(thumbnail) {
		var w = thumbnail.width() + 20;
		var h = thumbnail.height() + 20;
		thumbnail.parents('.img_holder').css( {
			'width' : w + 'px',
			'height' : h + 'px',
			'margin-top' : parseInt(-h * 0.5, 10) + 'px',
			'margin-right' : 'auto',
			'margin-bottom' : '0',
			'margin-left' : 'auto',
			'top' : '50%'
		});

		if ($('body').attr('id') === 'photos' && window.faces && faces.length) {
			var id = thumbnail.parents('.img_holder').attr('id');
			for ( var i = 0; i < faces.length; i++) {
				if ("inst-" + faces[i].imageInstanceId === id) {
					var imageInstanceId = faces[i].imageInstanceId;

					var thumb = $('#inst-' + imageInstanceId + ' img');
					var faceboxes = faces[i].faceboxes;
					if (faceboxes != null) {
						for ( var j = 0; j < faceboxes.length; j++) {
							var sizes = this.getThumbnailSize(thumb, faceboxes[j], faces[i].imageWidth);
							this.setThumbnailPositionAndFacebox(imageInstanceId, faces[i].imageMd5, faceboxes[j], sizes, '#inst-' + imageInstanceId, faces[i].imageOwnerId);
						}
					}
				}
			}
		}
	};

	// init jcrop
	this.photo = function(image) {

		o.cache.top = (image.parent().height() - image.height()) / 2;
		o.cache.box = [ (image[0].offsetWidth / 2 - 60), (image[0].offsetHeight / 2 - 60), (image[0].offsetWidth / 2 + 40), (image[0].offsetHeight / 2 + 40) ];
		o.cache.src = image.attr('src');
		o.cache.node = $.Jcrop(image, {
			borderOpacity : 0.7,
			handleOpacity : 1,
			aspectRatio : true,
			sideHandles : false,
			bgColor : 'transparent',
			boxTop : o.cache.top,
			setSelect : o.cache.box
		});
	};

	// update main img
	this.update = function() {
		var face;
		// update image
		$.Face.replace(window.faces, o.cache.face.photoInfo);
		face = $.Face.render(o.cache.face.photoInfo.imageInstanceId);
		$.Face.names(face);
	};
	this.handleKeyPressed = function(keyCode) {
		// handling esc pressed
		if (keyCode == 27) {
			ModalUtils.deleteModal();
			return false;
		}

		return true;
	};

	this.facebox = {
		// render facebox
		render : function(modalForm, elem, ratio, data) {
			var newFaceboxDiv = FACEBOX_HTML_TEMPLATE;

			var faceboxSize = elem.faceboxSize * ratio;
			var faceboxWidth = Math.round(faceboxSize);
			var faceboxHeight = Math.round(faceboxSize);

			var faceboxTop = Math.round(elem.faceboxY * ratio);
			var faceboxLeft = Math.round(elem.faceboxX * ratio);

			newFaceboxDiv = newFaceboxDiv.replace("__LEFT__", faceboxLeft);
			newFaceboxDiv = newFaceboxDiv.replace("__TOP__", faceboxTop);
			newFaceboxDiv = newFaceboxDiv.replace("__WIDTH__", faceboxWidth);
			newFaceboxDiv = newFaceboxDiv.replace("__HEIGHT__", faceboxHeight);
			if (elem.faceboxName != null && elem.faceboxName.nameeScreenName != null) {
				var name = elem.faceboxName.nameeScreenName;
				if (elem.faceboxName.nameeScreenName.length > 25) {
					name = elem.faceboxName.nameeScreenName.substring(0, 25) + '...';
				}
				newFaceboxDiv = newFaceboxDiv.replace(/__NAME__/g, name);
			} else {
				if (elem.faceboxName.locked) {
					newFaceboxDiv = newFaceboxDiv.replace(/__NAME__/g, "Private");
				} else {
					newFaceboxDiv = newFaceboxDiv.replace(/__NAME__/g, "Unnamed");
				}
			}
			var faceboxesContainer = modalForm.find(".photo_container .faceboxes");
			faceboxesContainer.append(newFaceboxDiv);

			var newNameDiv = "";
			if (elem.faceboxName.userCanDeleteThisName) {
				newNameDiv = NAME_HTML_TEMPLATE;
			} else {
				newNameDiv = NAME_LOCKED_HTML_TEMPLATE;
			}

			if (!elem.faceboxName.locked) {
				if (elem != null && elem.faceboxName != null && elem.faceboxName.nameeScreenName != null) {

					newNameDiv = newNameDiv.replace(/__FACEBOX_UUID__/g, elem.faceboxUuid);
					newNameDiv = newNameDiv.replace(/__FACEBOX_ID__/g, elem.faceboxId);
					newNameDiv = newNameDiv.replace(/__FACEBOX_ID__/g, elem.faceboxId);
					newNameDiv = newNameDiv.replace(/__IMAGE_MD5__/g, data.photoInfo.imageMd5);
					newNameDiv = newNameDiv.replace(/__IMAGE_INSTANCE_ID__/g, data.photoInfo.imageInstanceId);

					var name = "";

					if (elem.faceboxName != null) {
						name = elem.faceboxName.nameeScreenName;
						if (elem.faceboxName.nameeScreenName.length > 25) {
							name = elem.faceboxName.nameeScreenName.substring(0, 25) + '...';
						}
					} else {
						name = "Private";
					}
					newNameDiv = newNameDiv.replace(/__NAME__/g, name);
				} else {
					newNameDiv = UNKNOWN_HTML_TEMPLATE;
				}
			} else {
				newNameDiv = LOCKED_HTML_TEMPLATE;
			}
			var namesContainer = modalForm.find(".meta .names");
			namesContainer.append(newNameDiv);
		}
	};

	this.saveName = function() {
		var name = $(o.modalname + ' input[type=text]:first').val();

		var formToSubmit = $(o.modalname);
		if (!ModalUtils.validateNameForInput(formToSubmit.find("input[name=name]"))) {
			return false;
		}
		GeneralUtils.autocomplete.getEmail();
		ModalUtils.showModalLoadingProgress();
		ModalUtils.submitModalForm(formToSubmit, function(data) {
			formToSubmit.fadeOut(600, function() {
				$(this).remove();
			});

			$('#loading').remove();
			$(o.modal).show();

			ModalUtils.getAjaxJson(o.cache.href, function(data) {
				o.cache.face = data;
				var modalForm = $(o.modal);
				var img = modalForm.find(".photo_container img");
				var imageWidth = data.photoInfo.imageWidth;
				
				GeneralUtils.autocomplete.updateContactListWithNewData(data.newContact);
				
				var thumbWidth = img.width(); // img invisible
					var thumbHeight = img.height(); // img invisible
					var ratio = thumbWidth / imageWidth;
					modalForm.find(".meta .names").empty();
					modalForm.find(".photo_container .faceboxes").empty();
					if (data.photoInfo.faceboxes.length) {
						modalForm.find(".meta").prepend(META_TEMPLATE);
					} else {
						modalForm.find(".meta em:first").remove();
					}
					$.each(data.photoInfo.faceboxes, function() {
						global.facebox.render(modalForm, this, ratio, o.cache.face);
					});
				});

			o.cache.node.setSelect(o.cache.box);
		});

		return false;
	};

	this.photoEvents = function() {
		// hover selection
		$('.meta .names .name').live('mouseover', function() {
			var i = $(this).prevAll('.name').length;
			$(this).toggleClass('hover');
			$(o.modal + ' .facebox:eq(' + i + ')').toggleClass('hover');
			$(o.modal + ' .jcrop-holder').addClass('inactive');
		}).live('mouseout', function() {
			var i = $(this).prevAll('.name').length;
			$(this).toggleClass('hover');
			$(o.modal + ' .facebox:eq(' + i + ')').toggleClass('hover');
			$(o.modal + ' .jcrop-holder').removeClass('inactive');
		});
		// edit photo link
		$(o.editbutton).live('click', function() {
			o.cache.href = $(this).attr("_href");
			var faceLinkUrl = $(this).attr("_href");
			o.cache.container = $(this).parents('ul:first');

			ModalUtils.showModalLoadingProgress();
			ModalUtils.getAjaxJson($(this).attr("_href"), function(data) {
				o.cache.face = data;
				o.cache.oldface = data;

				ModalUtils.currentModalObject = global;
				var modalForm = ModalUtils.retrieveHtmlTemplateById("modal-edit_photo");
				var img = modalForm.find('img.thumbnail');

				modalForm.find("[name=imageInstanceId]").attr("value", data.actionBean.imageInstanceId);
				modalForm.find("[name=imageMD5]").attr("value", data.actionBean.imageMD5);
				modalForm.find("[name=userId]").attr("value", data.actionBean.userId);

				img.load(function() {
					// img.css('background-image', '');

						$('#loading').remove();
						ModalUtils.replaceIdAttributes(modalForm);
						ModalUtils.createAndResizeModal(modalForm);

						global.photo(img);

						// unbind close event
						modalForm.find("a.close_modal, .control a.close, .control a.cancel").unbind('click');

						img.css('background', '#fefefe no-repeat scroll 50% 50%');

						var imageWidth = data.photoInfo.imageWidth;
						var thumbWidth = img.width(); // img invisible
						var thumbHeight = img.height(); // img invisible
						var ratio = thumbWidth / imageWidth;
						modalForm.find("[name=thumbnailWidth]").attr("value", thumbWidth);
						modalForm.find("[name=thumbnailHeight]").attr("value", thumbHeight);

						if (data.photoInfo.faceboxes.length) {
							modalForm.find(".meta").prepend(META_TEMPLATE);
						} else {
							modalForm.find(".meta em:first").remove();
						}

						$.each(data.photoInfo.faceboxes, function() {
							global.facebox.render(modalForm, this, ratio, o.cache.face);
						});

						modalForm.find('.jcrop-holder').append(modalForm.find('.faceboxes'));

					});

				var imageSrcPrefix = img.attr("_src");
				img.attr("src", imageSrcPrefix + data.actionBean.imageMD5);
			})

			return false;
		});

		// confirm delete person
		$(o.modal + ' .delete').live('click', function() {
			o.cache.del = $(this).parent();

			ModalUtils.getAjaxJson(this.href, function(data) {
				var modalForm = ModalUtils.retrieveHtmlTemplateById("modal-delete_confirm");
				modalForm.find("[name=imageInstanceId]").attr("value", data.actionBean.imageInstanceId);
				modalForm.find("[name=imageMD5]").attr("value", data.actionBean.imageMD5);
				modalForm.find("[name=faceboxId]").attr("value", data.actionBean.faceboxId);
				modalForm.find("[name=faceboxUuid]").attr("value", data.actionBean.faceboxUuid);
				modalForm.find("[name=imageInstanceId]").attr("value", data.actionBean.imageInstanceId);
				modalForm.find("[name=userId]").attr("value", data.actionBean.userId);
				ModalUtils.replaceIdAttributes(modalForm);
				ModalUtils.createAndResizeModal(modalForm, true);

				// unbind close event
					modalForm.find("a.close_modal, .control a.close, .control a.cancel").unbind('click');
				});
			return false;
		});

		// modal add new person
		$(o.modal + ' a.done').live('click', function() {
			var formToSubmit = $(o.modal);

			// get select dimension
				o.cache.pos = o.cache.node.tellSelect();
				$('[name=faceboxX]').val(o.cache.pos.x);
				$('[name=faceboxY]').val(o.cache.pos.y);
				$('[name=faceboxSize]').val(o.cache.pos.w);

				ModalUtils.showModalLoadingProgress();
				ModalUtils.submitModalForm(formToSubmit, function(data) {
					var modalForm = ModalUtils.retrieveHtmlTemplateById("modal-edit-photo-who_is_this");
					modalForm.find("[name=faceboxX]").attr("value", data.actionBean.faceboxX);
					modalForm.find("[name=faceboxY]").attr("value", data.actionBean.faceboxY);
					modalForm.find("[name=faceboxSize]").attr("value", data.actionBean.faceboxSize);
					modalForm.find("[name=thumbnailWidth]").attr("value", data.actionBean.thumbnailWidth);
					modalForm.find("[name=thumbnailHeight]").attr("value", data.actionBean.thumbnailHeight);
					modalForm.find("[name=faceboxUuid]").attr("value", data.actionBean.faceboxUuid);
					modalForm.find("[name=userId]").attr("value", data.actionBean.userId);
					modalForm.find("[name=imageInstanceId]").attr("value", data.actionBean.imageInstanceId);
					modalForm.find("[name=imageMD5]").attr("value", data.actionBean.imageMD5);
					modalForm.find("[name=cropedX]").attr("value", data.actionBean.cropedX);
					modalForm.find("[name=cropedY]").attr("value", data.actionBean.cropedY);
					modalForm.find("[name=cropedSize]").attr("value", data.actionBean.cropedSize);

					ModalUtils.replaceIdAttributes(modalForm);
					ModalUtils.createAndResizeModal(modalForm, true);

					Bindings.addNamingModalBindings(); // fix for SWOOPSK-1088

						GeneralUtils.autocomplete = new AutoComplete("#modal-edit-photo-who_is_this input#name-field", "#modal-edit-photo-who_is_this #autocompleter", function(result) {
							if (result) {
								$("#modal-edit-photo-who_is_this #nameeIdentityId").val(result.defaultIdentityId);
							}
						}, 3, function() {
							/* enter pressed: trying to submit name */
							global.saveName();
							return false;
						}, '#modal-edit-photo-who_is_this');

						$('#suggestion_label').hide();
						$('#no-button').css('visibility', 'hidden');
						modalForm.find("input[name=name]").focus();

						$('#name-field').focus(function() {
							ModalUtils.focusOnInputWithDefaultValue(this, ModalUtils.defaultName);
						}).blur(function() {
							if (GeneralUtils.autocomplete) {
								GeneralUtils.autocomplete.chooseSelectedValue();
							}
							// ModalUtils.blurFromInputWithDefaultValue(this,
							// ModalUtils.defaultName);
							});
						modalForm.filter("#modal-edit-photo-who_is_this").find(".reset").click(function() {

							$('.name-input #name-field').attr('value', '');
							$('#modal-edit-photo-who_is_this').find("[name=email]").attr('value', '');
							$('#modal-edit-photo-who_is_this').find("[name=nameeUserId]").attr('value', '');
							$('#modal-edit-photo-who_is_this').find("[name=nameeIdentityId]").attr('value', '');
							$('#name-field').attr('value', 'Unknown Person');
							$('#name-field').removeClass('focused');
							$('#name-field').removeClass('named');
							$('#autocompleter').hide();
							$('#modal-edit-photo-who_is_this .message').removeClass('not_visible');
							$('#add_email').remove();
							$(this).hide();
							return false;
						});

						$('#name-field').focus();
						/* unbind close event */
						modalForm.find("a.close_modal, .control a.close, .control a.cancel").unbind('click');

						var face = $('#modal-edit-photo-who_is_this .edit_face_container .photo img');

						var imageSrcPrefix = face.attr("_src");
						face.attr("src", imageSrcPrefix + data.actionBean.faceboxUuid);
					});

				return false;
			});

		$(o.modalClose).live('click', (global.close));
	};

	this.namedEvents = function() {
		// add new person
		$(o.modalname + ' a.save').live('click', function() {
			global.saveName();
		});
		// close name modal
		$(o.modalnameClose).live('click', function() {
			var formToSubmit = $(o.modalname);
			formToSubmit.fadeOut(600, function() {
				$(this).remove();
			});
			$(o.modal).show().fadeIn(500);
			return false;
		});
	};

	this.deleteEvents = function() {
		/* delete person */
		$(o.modalclose + ' .control .delete').live('click', function() {
			var formToSubmit = $(o.modalclose);

			ModalUtils.showModalLoadingProgress();
			ModalUtils.submitModalForm(formToSubmit, function(data) {

				o.cache.face = data;

				var modalForm = $(o.modal);
				var img = modalForm.find(".photo_container img");
				var imageWidth = data.photoInfo.imageWidth;

				var thumbWidth = img.attr('width');
				var thumbHeight = img.attr('height');

				var ratio = thumbWidth / imageWidth;
				modalForm.find(".meta .names").empty();
				modalForm.find(".photo_container .faceboxes").empty();

				if (!data.photoInfo.faceboxes.length)
					modalForm.find(".meta em:first").remove();

				$.each(data.photoInfo.faceboxes, function() {
					global.facebox.render(modalForm, this, ratio, o.cache.face);
				});

				$('#loading').remove()

				formToSubmit.fadeOut(600, function() {
					$(this).remove();
				});
				$(o.modal).show();
			});

			return false;
		})
		// close modal delete
		$(o.modalcloseClose).live('click', function() {
			var formToSubmit = $(o.modalclose);
			formToSubmit.fadeOut(600, function() {
				$(this).remove();
			});
			$(o.modal).show();
			return false;
		});
	};

};