/*******************************************************
 * ops_modal.js - Modal box scripts
 ******************************************************/

// Used to put modal window to top on click or drag
modal_z_index = 901;

/**
 * Define an element on the page as a trigger for a modal window.
 * @param trigger The element which initiates the modal window
 * @param triggerType The aspect of the element which causes the trigger e.g. 'link', 'formSubmit'.
 * @param form The form element, if one is involved.
 * @param styles CSS Classes to apply to the modal window.
 * @returns {*|jQuery|number}
 */
function initiateModal(trigger, triggerType, form, styles) {

	var triggerJq = $(trigger);
	var hasHeader = true;
	var isLocked = false;

	if (triggerType == 'link') {
		var link = $(trigger).attr('href');
		var text = $(trigger).attr('title');
		$('body').append("<form class='ops_page_modal_hiddenform' action='" + link + "' method='post'></form>");
		var form = $('.ops_page_modal_hiddenform');
	} else if (triggerType == 'formSubmit') {
		var text = "text etc";
	} else if (triggerType == 'dialogueConfirm') {
	} else if (triggerType == 'option') {
		var text = $(trigger).parent('select').attr('title');
	} else if (triggerType == 'cell') {
		var link = $(trigger).attr('href');
		$('body').append("<form class='ops_page_modal_hiddenform' action='" + link + "' method='post'></form>");
		var form = $('.ops_page_modal_hiddenform');
	} else if (triggerType == 'lock') {
		// Lock until system action (Esc and header+button disabled)
		var text = $('.ops_page_modal_message', triggerJq).first().html();
		if (!text) {
			text = '<p class="ops_page_default_modal_message">Please wait&hellip;</p>';
		}
		hasHeader = false;
		isLocked = true;
	}

	if ($(trigger).is('.ops_page_modal_self')) {
		var index = $(trigger).closest('.ops_page_modal_instance').attr('id');
	} else {
		var index = createModal(trigger, styles, hasHeader, isLocked);
	}

	// Two ways of determining type? By class and by triggerType?
	if ($(trigger).is('.ops_page_modal_lock')) {
		setModalDialogueMessage(index, text, true);
		positionModal(index, true);
		return index;
	}

	// If the triggered modal is just a confirm box (no external content).
	if ($(trigger).is('.ops_page_modal_confirm')) {
		setModalDialogue(index);
		var strippedTrigger = $(trigger)
			.removeClass('ops_page_modal_confirm')
			.addClass('ops_page_modal_confirm_supressed');

		setModalDialogueConfirm(index, text, form, strippedTrigger);
		positionModal(index, true);
		return index;
	}

	// If the triggered modal is a webpage - AJAX and return its content.
	if ($(trigger).is('.ops_page_modal')) {
		getModalContent(index, form);
		positionModal(index, false);
		if ($(trigger).is('.ops_page_modal_confirm_supressed')) {
			$(trigger).removeClass('ops_page_modal_confirm_supressed').addClass('ops_page_modal_confirm');
		}
	} else {
		form.submit();
	}
}

/**
 * Generate the HTML for the modal background and window.
 * @param trigger The triggering element. Can be JS Element or jQuery.
 * @param styles CSS Classes to apply to the modal window.
 * @param showHeader The window header containing the 'X' close button.
 * @param isLocked FALSE if the modal window can be closed with an ESC press, TRUE otherwise.
 * @returns {number|jQuery}
 */
function createModal(trigger, styles, showHeader, isLocked) {

	if (styles === undefined) {
		styles = '';
	}
	if (showHeader === undefined) {
		showHeader = true;
	}
	if (isLocked === undefined) {
		isLocked = false;
	}

	var windowWidth = document.documentElement.scrollWidth;

	var modalIndex = $('.ops_page_modal_instance').length;
	createModalBackground() ;

	html = "<div class='ops_page_modal_instance " + styles + "' id='" + modalIndex + "'>";
	// Optional header
	if (showHeader) {
		html += "<div class='ops_page_modal_header'><button class='ops_page_modal_button_close' tabindex='0' aria-label='Close'></button></div>";
	}
	html += "<div class='ops_page_modal_content' tabindex='-1'></div></div>";

	$(html).hide().appendTo('body').fadeIn(300);

	var modal = $('.ops_page_modal_instance[id=' + modalIndex + ']');
	var modalWidth = $(modal).width();

	$(modal).find('.ops_page_modal_button_close').on('click touchstart', function () {
		closeModal(modalIndex, true);
		if ($(trigger).is('.ops_page_modal_confirm_supressed')) {
			$(trigger).removeClass('ops_page_modal_confirm_supressed').addClass('ops_page_modal_confirm');
		}
	});

	$(modal).click(function () {
		modalToFront(modalIndex, isLocked);
	}).on('dragstart', function () {
		modalToFront(modalIndex, isLocked);
	});

	if (!isLocked) {
		$(document).keyup(function (e) {
			if (e.keyCode == 27) {
				closeModal(modalIndex, true);
			}
		});
	}

	modalToFront(modalIndex, isLocked);
	var modal_z_index = modal_z_index - 1;

	makeWindowed(modal);
	makeWindowed($('.ops_page_modal_background'));

	$(modal).draggable({
		handle: '.ops_page_modal_header',
		containment: [0, 0, windowWidth - modalWidth, 10000]
	});

	return modalIndex;

}

function closeModal(index, modalComplete) {

	$('.ops_page_modal_instance[id=' + index + ']').fadeOut(200, function () {
		$(this).remove();
	});

	// Remove lightbox effect only when the last modal instance is being removed
	if ($('.ops_page_modal_instance').length <= 1) {
        destroyModalBackground();
	}

	if (modalComplete == true) {
		$('.ops_datagrid_options_selections_tasks').each(function () {
			$(this).find('option:first-child').attr('selected', 'selected');
		});
		$('form').find('input[name=ops_page_modal_dialogue_confirm]').remove();
	}
	$(document).unbind('keyup');

}

function createModalBackground() {
    if ($('.ops_page_modal_background').length == 0) {
        html = "<div class='ops_page_modal_background'></div>";
        $(html).hide().appendTo('body').fadeIn(200);

    }
}

function destroyModalBackground() {
    $('.ops_page_modal_background').fadeOut(200, function () {
        $(this).remove();
    });
}

function positionModal(index, centre) {

	var modal = $('.ops_page_modal_instance[id=' + index + ']');

	var scroll_y = getScrollPosY();

	var windowWidth = document.documentElement.clientWidth;
	var windowHeight = document.documentElement.clientHeight;
	var modalHeight = $(modal).height();
	var modalWidth = $(modal).width();
	var displace_top = ((windowHeight / 2 - modalHeight / 2) + scroll_y);
	var displace_left = (windowWidth / 2 - modalWidth / 2);
	if (displace_top < scroll_y) {
		displace_top = scroll_y;
	}
	$(modal).css({
		'top': displace_top + "px",
		'left': displace_left + "px"
	});
	positionModalBackground();

}

function positionModalBackground() {

	var scroll_y = getScrollPosY();

	$('.ops_page_modal_background').css({'top': scroll_y + "px"});

}

/**
 * Populate a modal window's content with an AJAX HTTP response from an endpoint specified in the
 * modal trigger.
 * @param index The index of the modal window waiting to be filled with content.
 * @param form A form element storing the details of the modal trigger. This form may be
 *        taken from the modal trigger or was generated earlier in this script as a hidden element.
 */
function getModalContent(index, form) {

	var modal = $('.ops_page_modal_instance[id=' + index + ']');
	$(document).ajaxError(function (e, xhr, settings, exception) {
		//alert(exception);
		if ($(form).is('.ops_form_modal')) {
			closeModal(index, true);
		} else {
			$(modal).find('.ops_page_modal_content').empty();
			setModalDialogue(index);
			setModalDialogueError(index, settings.url);
		}
	});

	$(modal)
		.find('.ops_page_modal_content')
		.html("<p class='ops_page_ajaxloading modal_loading'>Please wait</p></div>");

	var link = $(form).attr('action');
	$(form).append("<input type='hidden' name='ops_page_modal' value='1' />");
	$.ajax({
		type: "POST",
		url: link,
		data: encodeURIComponent($(form).serialize()),
		dataType: 'text', //change to just text from text/html for jquery 1.5 and higher
		success: function (data, status, XMLHttpRequest) {
			$(modal).find('.ops_page_modal_content').html(data);

			bindModalTrigger(modal);
			$(modal).unbind('ajaxError');
			var maxWidth = 800;
			$(modal).find('.ops_page_modal_content').find('html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td').each(function () {
				if ($(this).width() > maxWidth) {
					maxWidth = $(this).width();
				}
			});
			$(modal).css({'width': (maxWidth + 20) + "px"});
			$(modal).find('.ops_form.ops_page_modal').submit(function (event) {
				event.preventDefault();
			});
			positionModal(index, false);
			$(modal).find('.ops_page_modal_content').focus();
		}
	});
	$('.ops_page_modal_hiddenform').remove();
}

function setModalDialogue(index) {
	var windowWidth = document.documentElement.scrollWidth;
	var modalWidth = $('.ops_page_modal_instance[id=' + index + ']').width();

	$('.ops_page_modal_instance[id=' + index + ']').addClass('ops_page_modal_dialogue').children('.ops_page_modal_content').append(
		"<div class='ops_page_modal_dialogue_text'></div>" +
		"<div class='ops_page_modal_dialogue_buttons'></div>"
	);

	$('.ops_page_modal_instance[id=' + index + ']').draggable({
		handle: '.ops_page_modal_header',
		containment: [0, 0, windowWidth - modalWidth, 10000]
	});
	positionModal(index);
}

/**
 * Find the text container, if none found get the
 * content container, add a text container to it and return ref
 */
function findModalDialogueText(index) {
	var dialogue = $('.ops_page_modal_instance[id=' + index + ']').first();
	var textTarget = $('.ops_page_modal_dialogue_text', dialogue);
	if (!textTarget.length) {
		var content = dialogue.find('.ops_page_modal_content').first();
		if (content.length) {
			textTarget = content.append('<p class=".ops_page_modal_text"></p>');
		} else throw "No modal content container was found!"
	}
	return textTarget;
}

/**
 * Sets modal text message by appending or optionally replacing
 */
function setModalDialogueMessage(index, text, replace) {
	if (replace === undefined) {
		replace = false;
	}
	var textTarget = findModalDialogueText(index);
	if (replace) {
		textTarget.html("<p>" + text + "</p>");
	} else {
		textTarget.append("<p>" + text + "</p>");
	}
}

function setModalDialogueConfirm(index, text, prevForm, prevTrigger) {

	var dialogue = $('.ops_page_modal_instance[id=' + index + ']');
	setModalDialogueMessage(index, text);

	$(dialogue).find('.ops_page_modal_dialogue_buttons').append(
		"<div class='ops_page_modal_dialogue_button ops_page_modal_dialogue_button_confirm ops_page_hovershadow'>Confirm</div>" +
		"<div class='ops_page_modal_dialogue_button ops_page_modal_dialogue_button_cancel ops_page_hovershadow'>Cancel</div>"
	);

	$('.ops_page_modal_dialogue_button_confirm').click(function () {
		var modalIndex = $(this).closest('.ops_page_modal_instance').attr('id');
		closeModal(modalIndex);
		$(prevForm).append("<input type='hidden' name='ops_page_modal_dialogue_confirm' value='1' />");
		initiateModal(prevTrigger, 'dialogueConfirm', prevForm);
	});

	$('.ops_page_modal_dialogue_button_cancel').click(function () {
		closeModal(index, true);
		if ($(prevTrigger).is('.ops_page_modal_confirm_supressed')) {
			$(prevTrigger).removeClass('ops_page_modal_confirm_supressed').addClass('ops_page_modal_confirm');
		}
	});

}

function setModalDialogueError(index, page) {

	var dialogue = $('.ops_page_modal_instance[id=' + index + ']');


	$(dialogue).find('.ops_page_modal_dialogue_text').append("<p>An error has occured whilst requesting: <br/>" + document.URL + "</p>");

	$(dialogue).find('.ops_page_modal_dialogue_buttons').append(
		"<div class='ops_page_modal_dialogue_button ops_page_modal_dialogue_button_confirm ops_page_hovershadow'>OK</div>"
	);
	$('.ops_page_modal_dialogue_button_confirm').click(function () {
		var modalIndex = $(this).closest('.ops_page_modal_instance').attr('id');
		closeModal(modalIndex);
		//
		window.location = page;
	});
	$('.ops_page_modal_button_close').remove();
	$('.ops_page_modal_dialogue_buttons').css({'width': '142px'});


}

/**
 * Bind the modal trigger events to an element or any of its descendants provided they are marked
 * as a modal trigger.
 * @param element
 */
function bindModalTrigger(element) {

	if (!element) {
		var element = $('body');
	}

	// Bind modals that are set to automatically load on page load.
	// Limit of one auto-loading modal per page, to stop potentially overflowing
	// users with multiple popups.
	$(element).find('a.ops_page_modal_autoload').eq(0).each(function () {
		initiateModal($(this), 'link');
	});

	$(element).find('a.ops_page_modal, a.ops_page_modal_confirm').click(function (event) {
		initiateModal($(this), 'link');
		event.preventDefault();
	});
	$(element).find('select').change(function (event) {
		if ($(this).find('option:selected').is('.ops_page_modal') || $(this).find('option:selected').is('.ops_page_modal_confirm')) {
			initiateModal($(this).find('option:selected'), 'option', $(this).parent('form'));
		} else if ($(this).is('.ops_form_select_submit')) {
			if ($(this).find('option:selected').index() == 0) {

			} else {
				this.form.submit();
			}
		}
	});
	$(element).find('form.ops_page_modal, form.ops_page_modal_dialogue').submit(function (event) {
		initiateModal($(this), 'formSubmit', $(this));
	});
	$(element).find('td.ops_page_modal, th.ops_page_modal').each(function () {
		$(this).click(function () {
			initiateModal($(this), 'cell');
		});
	});

}

function bindFormSubmit(index) {

	$('.ops_page_modal_instance:eq(' + index + ')').find('.ops_form.ops_page_modal').each(function () {
		$(this).submit(function (event) {
			event.preventDefault();
			getModalContent(index, this);
		});
	});

}

/**
 *
 * @param index The index of the modal window to bring to front.
 * @param isLocked If the modal window can be closed with an ESC press.
 */
function modalToFront(index, isLocked) {

	if (isLocked === undefined) {
		isLocked = false;
	}

	$(document).unbind('keyup');
	$('.ops_page_modal_instance:eq(' + index + ')').css({'z-index': modal_z_index});
	modal_z_index++;
	if (!isLocked) {
		$(document).keyup(function (e) {
			if (e.keyCode == 27) {
				closeModal(index, true);
			}
		});
	}
}

function getScrollPosY() {

	if (typeof (window.pageYOffset) == 'number') { // Netscape compliant
		var scroll_y = window.pageYOffset;
	} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { // DOM compliant
		var scroll_y = document.body.scrollTop;
	} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { // IE6 standards compliant mode
		var scroll_y = document.documentElement.scrollTop;
	} else {
		var scroll_y = 0;
	}

	return scroll_y;

}

/**
 * Make the specified div a windowed control in IE6.
 * This will do nothing for all other browsers.
 * This masks an iframe (which is a windowed control) onto the div, turning the div into a windowed control itself.
 * @param p_div
 */
function makeWindowed(p_div) {

	var is_ie6 =
		document.all &&
		(navigator.userAgent.toLowerCase().indexOf("msie 6.") != -1);

	if (is_ie6) {
		var html = "<iframe style=\"position: absolute; display: block; " +
			"z-index: -1; width: 100%; height: 100%; top: 0; left: 0;" +
			"filter: mask(); background-color: #ffffff; \"></iframe>";
		if (p_div) $(p_div).append(html);
		// force refresh of div
		var olddisplay = $(p_div).css('display');
		$(p_div).css({'display': 'none'});
		$(p_div).css({'display': olddisplay});
	}
	;

}
