// Functions for the regenerating of images
var rahe;
if (!rahe) {
	rahe = {};
} else if (typeof rahe !== "object") {
	throw new Error('rahe already exists and not an object');
}

if (!rahe.sis) {
	rahe.sis = {};
} else if (typeof rahe.sis !== "object") {
	throw new Error('rahe.sis already exists and not an object');
}

rahe.sis.regenerate = {
	post_types: [],
	thumbnails: [],
	total: 0,
	cur: 0,
	timeScript: [],
	dateScript: '',
	percent: '',
	percentText: null,
	progress: null,
	messageZone: null,
	sisZone: null,
	time: null,
	timeZone: null,
	buttonRegenerate: null,
	errorZone: null,
	errorMessages: null,
	thumb: null,
	thumbImg: null,
	init: function () {
		this.sisZone = jQuery('.sis');
		this.percentText = jQuery('#sis_progress-percent');
		this.progress = jQuery('.progress');
		this.messageZone = this.sisZone.find(".regenerate_message");
		this.time = this.sisZone.find(".time");
		this.timeZone = this.time.find("p span.time_message");
		this.buttonRegenerate = jQuery("#ajax_thumbnail_rebuild");
		this.errorZone = jQuery('#error_messages');
		this.errorMessages = this.errorZone.find('ul.messages');
		this.thumb = this.sisZone.find('.thumb');
		this.thumbImg = this.sisZone.find('.thumb-img');
	},
	getThumbnails: function () {
		var self = this,
			inputs = jQuery('input.thumbnails:checked');

		// Get the checked thumbnails inputs
		if (inputs.length != jQuery('input.thumbnails[type="checkbox"]').length) {
			inputs.each(function (i) {
				self.thumbnails.push(this.value);
			});
		}
	},
	getPostTypes: function () {
		var self = this,
			inputs = jQuery('input.post_types:checked');

		// Get the checked post Types inputs
		if (inputs.length != jQuery('input.post_types[type="checkbox"]').length) {
			inputs.each(function () {
				self.post_types.push(this.value);
			});
		}
	},
	setMessage: function (msg) {
		// Display the message
		this.messageZone.html("<p>" + msg + "</p>").addClass('updated').addClass('fade').show();
	},
	setTimeMessage: function (msg) {
		this.timeZone.html(msg);
	},
	checkStartRegenerating: function () {
		if (jQuery('.notSaved').size() > 0) {
			var confirmation = confirm(sis.notSaved);

			// Delete if ok else not delete
			if (confirmation == true) {
				this.startRegenerating();
			} else {
				return false;
			}
		} else {
			this.startRegenerating();
		}
	},
	startRegenerating: function () {
		var self = this,
			wp_nonce = jQuery('input.getList').val();

		// Get the humbnails and post types
		self.getThumbnails();
		self.getPostTypes();

		this.dateScript = new Date();
		// Start ajax
		jQuery.ajax({
			url: ajaxurl,
			type: "POST",
			dataType: 'json',
			data: {
				action: 'sis_get_list',
				post_types: self.post_types,
				nonce: wp_nonce
			},
			beforeSend: function () {

				// Disable the button
				self.buttonRegenerate.attr("disabled", true);
				// Display the message
				self.setMessage(sis.reading);

			},
			success: function (r) {

				if (typeof r !== 'object') {
					self.reInit();
					self.setMessage(sis.phpError);
					return false;
				}

				self.time.show();

				// Eval the response
				self.total = r.total;

				// Set the current to 0
				self.curr = 0;

				// Display the progress Bar
				self.progress.show().parent().show();

				// Start Regenerating
				self.regenItem();
			}
		});
	},
	regenItem: function () {
		var self = this,
			wp_nonce = jQuery('input.regen').val();

		// If the list is empty display the message of emptyness and reinitialize the form
		if (this.total == 0 || _.isUndefined(this.total)) {
			this.reInit();
			this.setMessage(sis.noMedia);
			return false;
		}

		// If we have finished the regeneration display message and init again
		if (this.curr >= this.total) {
			var now = new Date();
			this.reInit();
			this.setMessage(sis.done + this.curr + ' ' + sis.messageRegenerated + sis.startedAt + ' ' + this.dateScript.getHours() + ":" + this.dateScript.getMinutes() + ":" + this.dateScript.getSeconds() + sis.finishedAt + ' ' + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds());
			return;
		}

		// Set the message of current image regenerating
		this.setMessage(sis.regenerating + ( this.curr + 1 ) + sis.of + this.total);
		this.setMessage(sis.regenerating + ( this.curr + 1 ) + sis.of + this.total);

		jQuery.ajax({
			url: ajaxurl,
			type: "POST",
			dataType: 'json',
			data: {
				action: 'sis_rebuild_images',
				offset: this.curr,
				thumbnails: this.thumbnails,
				nonce: wp_nonce
			},
			beforeSend: function () {
				// Calculate the percentage of regeneration
				self.percent = ( self.curr / self.total ) * 100;

				// Change the progression
				self.progress.find('.bar').width(self.percent + '%')
					.find('.percent').html(self.percent + '%');

				// Change the text of progression
				self.percentText.removeClass('hidden').html(Math.round(self.percent) + "%");
			},
			success: function (r) {
				// Check if error or a message in response
				if (( !r.src || !r.time ) || r.error || typeof r !== 'object') {
					var message = '';
					if (typeof r !== 'object') {
						message = sis.phpError;
					} else {
						message = r.error
					}

					self.errorZone.addClass('error message');
					self.errorMessages.prepend('<li>' + message + '</li>');
				} else {

					// Append a message if needed
					if (r.message) {
						self.time.find('ul.messages').prepend('<li>' + r.message + '</li>');
					}

					// Display the image
					self.thumb.show();

					// Change his attribute
					self.thumbImg.attr("src", r.src);

					// Actual time
					var dateEnd = new Date(),
						curDate = new Date(),
						num = 0,
						sum = 0,
						i = 0,
						ave = 0,
						time = '';

					// Add the regenerating time to the array
					self.timeScript.push(parseFloat(r.time.replace(',', '.'), 10));

					// Get the number of elements in array
					num = self.timeScript.length;

					// Make the sum of the times
					for (i; i < num; i++) {
						sum += self.timeScript[i];
					}

					// Make the average value of the regenerating time
					ave = sum / num;

					// Round the value in miliseconds and add 25% or error
					t = Math.round(( ( ave * self.total ) * 1000 ));

					// Set the predicted time
					dateEnd.setTime(self.dateScript.getTime() + t);

					// Get the difference between the two dates
					time = self.s2t(Math.abs(( dateEnd.getTime() - curDate.getTime() )) / 1000);

					// Set the message in the notice box
					self.setTimeMessage(dateEnd.getHours() + ":" + dateEnd.getMinutes() + ":" + dateEnd.getSeconds() + sis.or + time + sis.beforeEnd);
				}

				// Inscrease the counter and regene the next item
				self.curr++;
				self.regenItem();
			}
		});

	},
	s2t: function (secs) {
		var secs = secs % 86400,
			t = new Date(1970, 0, 1),
			s = 0;

		t.setSeconds(secs);
		s = t.toTimeString().substr(0, 8);
		if (secs > 86399) {
			s = Math.floor(( t - Date.parse("1/1/70") ) / 3600000) + s.substr(2);
		}
		return s;
	},
	reInit: function () {
		// Re initilize the form
		this.buttonRegenerate.removeAttr("disabled");
		this.thumb.hide();
		this.progress.hide();
		this.percentText.addClass('hidden');
	}
};

rahe.sis.sizes = {
	i: 0,
	add: function (e, el) {
		e.preventDefault();

		// Create the template
		var elTr = rahe.sis.template('new_size');
		elTr = elTr({
			size_id: this.i,
			validate: sis.validate
		});

		// Add the form for editing
		jQuery(el).closest('tr').before(elTr);

		// Inscrease the identifier
		this.i++;
	},
	register: function (e, el) {
		// Stop propagation
		e.preventDefault();

		// Get name and id
		var name = jQuery(el).closest('tr').children('th').find('input').val(),
			id = jQuery(el).closest('tr').children('th').find('input').attr('id'),

		// Get the number of elements with this name
			checkPresent = jQuery(el).closest('tbody').find('input[value="' + name + '"]').length;

		// Check if not basic size or already present, display message
		if (name == 'thumbnail' || name == "medium" || name == "large") {
			alert(sis.notOriginal);
			return false;
		} else if (checkPresent != 0) {
			alert(sis.alreadyPresent);
			return false;
		}

		var row = rahe.sis.template('new_size_row');

		row = row({
			size: sis.size,
			size_name: name,
			maximumWidth: sis.maximumWidth,
			maximumHeight: sis.maximumHeight,
			customName: sis.customName,
			crop: sis.crop,
			crop_positions: sis.crop_positions,
			show: sis.show,
			deleteImage: sis.deleteImage,
			validateButton: sis.validateButton
		});

		// Add the row to the current list
		jQuery('#' + id).closest('tr').html(row);
	},
	deleteSize: function (e, el) {
		e.preventDefault();
		// Check if user want to delete or not
		var confirmation = confirm(sis.confirmDelete);

		// Delete if ok else not delete
		if (confirmation == true) {
			// Remove from the list and the array
			jQuery(el).closest('tr').remove();
			this.ajaxUnregister(el);
		}
	},
	getPhp: function (e, el) {
		e.preventDefault();
		// Get parent element
		var parent = jQuery(el).closest('tr');

		jQuery.ajax({
			url: ajaxurl,
			type: "POST",
			data: {action: "sis_get_sizes"},
			beforeSend: function () {
				// Remove classes of status
				parent.removeClass('addPending');
				parent.addClass('addPending');
			},
			success: function (result) {
				// Add the classes for the status
				jQuery('#get_php').nextAll('code').html('<br />' + result).show().css({'display': 'block'});
				parent.removeClass('addPending');
			}
		});
	},
	ajaxRegister: function (e, el) {
		e.preventDefault();

		// Get the vars
		var self = this,
			parentTable = jQuery(el).closest('table'),
			timer,
			wp_nonce = jQuery('.addSize').val(),
			parent = jQuery(el).closest('tr'),
			n = parent.find('input[name="image_name"]').val(),
			c = parent.find('select.crop').val(),
			s = parent.find('input.show').val(),
			cn = parent.find('input.n').val(),
			h = 0,
			w = 0;
		s = ( s == false || s == undefined ) ? false : true;
		w = parseInt(parent.find('input.w').val());
		h = parseInt(parent.find('input.h').val());

		if (!parentTable.hasClass('ajaxing')) {
			jQuery.ajax({
				url: ajaxurl,
				type: "POST",
				dataType: 'json',
				data: {
					action: "sis_add_size",
					width: w,
					height: h,
					crop: c,
					name: n,
					show: s,
					customName: cn,
					nonce: wp_nonce
				},
				beforeSend: function () {
					// Remove status and set pending
					parent.removeClass();
					parent.addClass('addPending');
					parentTable.addClass('ajaxing');
				},
				success: function (result) {
					// Set basic class and remove pending
					var classTr = '';
					parent.removeClass();
					parentTable.removeClass('ajaxing');

					// Check the result for the different messages
					if (result == 0) {
						classTr = 'errorAdding';
					} else if (result == 2) {
						classTr = 'notChangedAdding';

						// add/update to the array with the status class
						self.addToArray(n, w, h, c, classTr);
					} else {
						classTr = 'successAdding';

						// add/update to the array with the status class
						self.addToArray(n, w, h, c, classTr);
					}

					// Add the new sizes values for checking of changed or not
					parent.find('input.h').attr({base_h: h});
					parent.find('input.w').attr({base_w: w});
					parent.find('select.c').attr({base_c: c});
					parent.find('input.s').attr({base_s: s});

					// Add the generated class
					parent.addClass(classTr);
					parent.find('td').removeClass("notSaved");

					// Change the button text
					parent.find('.add_size').removeClass('validate_size').hide().children('.ui-button-text').text(sis.update);

					clearTimeout(timer);
					// Remove classes after 3 seconds
					timer = setTimeout(function () {
						parent.removeClass('errorAdding notChangedAdding successAdding');
					}, 2 * 1000);
				}
			});
		}
	},
	ajaxUnregister: function (el) {
		// Get name and self object
		var self = this,
			n = jQuery(el).closest('tr').find('input[name="image_name"]').val(),
			wp_nonce = jQuery(el).closest('tr').find('input.deleteSize').val();

		// Make the ajax call
		jQuery.ajax({
			url: ajaxurl,
			type: "POST",
			data: {action: "sis_remove_size", name: n, nonce: wp_nonce},
			success: function (result) {
				self.removeFromArray(el);
			}
		});
	},
	addToArray: function (n, w, h, c, s) {
		// Get the row for editing or updating
		var testRow = jQuery('#sis-' + n),
			newRow = '',
			timer;

		// Get the right newRow, updating or adding ?
		if (testRow.length != 0) {
			newRow = testRow.closest('tr');
		} else {
			newRow = jQuery('#sis-regen .wrapper > table#sis_sizes > tbody > tr:first').clone().attr('id', 'sis-' + n);
		}

		c = !_.isUndefined(sis.crop_positions[c]) ? sis.crop_positions[c] : sis.fl;

		// Set the datas with the given datas
		newRow.find('th > label').attr('for', n)
			.end()
			.find('input.thumbnails').val(n).attr('id', n)
			.end()
			.find('th:nth-child(2) > label').text(n)
			.end()
			.find('th:nth-child(3) > label').text(w + 'px')
			.end()
			.find('th:nth-child(4) > label').text(h + 'px')
			.end()
			.find('th:nth-child(5) > label').text(c);

		// If new then add the row
		if (testRow.length == 0) {
			newRow.appendTo('#sis-regen .wrapper > table#sis_sizes > tbody');
		}

		// Remove the previous status classes and add the status class
		newRow.removeClass('errorAdding notChangedAdding successAdding').addClass(s);

		clearTimeout(timer);
		// Remove the statuses classes
		timer = setTimeout(function () {
			newRow.removeClass('errorAdding notChangedAdding successAdding');
		}, 3 * 1000);
	},
	removeFromArray: function (el) {
		// get the name
		var n = jQuery(el).closest('tr').find('input[name=image_name]').val();

		// Remove the given name from the array
		jQuery('#sis-' + n).remove();
	},
	displayChange: function (el) {
		var el = jQuery(el),
			parent = el.closest('tr');

		// Check not new size
		if (parent.hasClass('new_size')) {
			return false;
		}

		var h_el = parent.find('input.h'),
			w_el = parent.find('input.w'),
			c_el = parent.find('select.c'),
			s_el = parent.find('input.s'),
			n_el = parent.find('input.n'),

			h = h_el.val(),
			w = w_el.val(),
			c = c_el.val(),
			s = s_el.val(),
			n = n_el.val(),

			base_h = h_el.attr('base_h'),
			base_w = w_el.attr('base_w'),
			base_c = c_el.attr('base_c'),
			base_s = s_el.attr('base_s'),
			base_n = n_el.attr('base_n');


		base_c = base_c == '0' ? false : true;
		base_s = base_s == '0' ? false : true;

		if (h != base_h || w != base_w || c != base_c || s != base_s || n != base_n) {
			el.closest('td').addClass('notSaved').find('.add_size').css('display', 'inline-block');
		} else {
			el.closest('td').removeClass('notSaved').find('.add_size').css('display', 'none');
		}
	}
};

rahe.sis.template = _.memoize(function (id) {
	var compiled,
		options = {
			evaluate: /<#([\s\S]+?)#>/g,
			interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
			escape: /\{\{([^\}]+?)\}\}(?!\})/g,
			variable: 'data'
		};

	return function (data) {
		compiled = compiled || _.template(jQuery('#sis-' + id).html(), null, options);
		return compiled(data);
	};
});

jQuery(function () {
	rahe.sis.regenerate.init();
	var bodyContent = jQuery('#wpbody-content');
	// Regeneration listener
	jQuery('#ajax_thumbnail_rebuild').click(function () {
		rahe.sis.regenerate.checkStartRegenerating();
	});

	// Add size button listener
	bodyContent.on('click', '#add_size', function (e) {
			rahe.sis.sizes.add(e, this);
		})

		// Registering a new size listener
		.on('click', '.add_size_name', function (e) {
			rahe.sis.sizes.register(e, this);
		})

		// Delete and Adding buttons
		.on('click', '.delete_size', function (e) {
			rahe.sis.sizes.deleteSize(e, this);
		})
		.on('click', '.add_size', function (e) {
			rahe.sis.sizes.ajaxRegister(e, this);
		})

		.on('click keyup change', '.h,.w,.c,.s,.n', function (e) {
			rahe.sis.sizes.displayChange(this);
		})

		// Seup the getphp
		.on('click', '#get_php', function (e) {
			rahe.sis.sizes.getPhp(e, this)
		});
	jQuery('#get_php').nextAll('code').hide();

	jQuery(".add_size").hide();
});