﻿/**
* Modal
* 
* Contains PLY authored JS classes used to power FreeClear modals.
*
* @author: PLY Interactive
* @dependency: jquery.js, jquery.simplemodal.js
**/

if (typeof FreeClear != 'object') FreeClear = {};
if (!FreeClear.UI) FreeClear.UI = {};

FreeClear.UI.Modal = function(newSettings) {

	// Private properties
	var _self = this;
	var _defaults = {
		'elementSelector': 'div[id$=modalPanel]',
		'allowResize': false,
		'minWindowMargin': 50,
		'minScrollHeight': 150,
		'onOpen': null,
		'onShow': null,
		'onClose': null
	};

	// Public properties
	this.settings = $.extend({}, _defaults, newSettings);
	this.baseObject = {};

	// Private methods
	var _open = function(modalHash) {
		modalHash.overlay.fadeIn(400, function() {
			modalHash.container.fadeIn(10, function() {
				$(modalHash.data).css('position', 'static');
				modalHash.data.fadeIn(400, function() {
					// Execute open callback if it exists
					if (typeof _self.settings.onOpen == 'function') {
						_self.settings.onOpen();
					}
				});
				if (_self.settings.allowResize) {
					// Fix modal height if it exceeds the window height
					_self.fixHeight(modalHash.data);
					// Setup window resize event handler
					$(window).resize(function() {
						_self.fixHeight(modalHash.data);
					});
				}
			});
		});
	};

	var _show = function(modalHash) {
		// Execute show callback if it exists
		if (typeof _self.settings.onShow == 'function')
			_self.settings.onShow();
	}

	var _close = function(modalHash) {
		modalHash.data.fadeOut(200, function() {
			modalHash.container.fadeOut(10, function() {
				modalHash.overlay.fadeOut(200, function() {
					// Execute close callback if it exists
					if (typeof _self.settings.onClose == 'function')
						_self.settings.onClose();
					// unbind resize event
					$(window).unbind('resize');
					// Call modal object's internal close method
					$.modal.close();
				});
			});
		});
	};

	// Public methods
	this.launch = function() {
		var modalObject = $(this.settings.elementSelector).modal({
			'opacity': 85,
			'overlayId': 'modalOverlay',
			'containerId': 'modalContainer',
			'closeClass': 'modalClose',
			'persist': true,
			'onOpen': _open,
			'onShow': _show,
			'onClose': _close
		});

		return modalObject;
	};

	// Fix the modal height if it exceeds the window height (minus margin)
	this.fixHeight = function($modal) {
		var _$scrollRegion = $modal.find('.scrollRegion');
		var _windowHeight = $.browser.safari ? $(window).attr('innerHeight') : $(window).height();
		var _maxHeight = _windowHeight - (_self.settings.minWindowMargin * 2);
		var _modalHeight = $modal.height();

		if (_$scrollRegion.length == 1) {
			var _scrollRegionHeight = _$scrollRegion.height();
			var _scrollHeight = _$scrollRegion.attr('scrollHeight')
			var _newScrollRegionHeight = _scrollRegionHeight;
			// Calculate new scroll region height
			if (_maxHeight < _modalHeight || (_scrollRegionHeight < _scrollHeight)) {
				_newScrollRegionHeight -= (_modalHeight - _maxHeight);
				_$scrollRegion.addClass('rule');
				if (_newScrollRegionHeight < _self.settings.minScrollHeight) {
					_newScrollRegionHeight = _self.settings.minScrollHeight;
				} else if (_newScrollRegionHeight >= _scrollHeight) {
					_newScrollRegionHeight = _scrollHeight;
					_$scrollRegion.removeClass('rule');
				}
			}
			// Set scroll region CSS height property
			_$scrollRegion.css('height', _newScrollRegionHeight + 'px');
		}

		/* Modal Height Needs to Use the outerHeight property to take into account padding on the parent
		or the css height + padding-top / padding-bottom */
		var _modalHeight = $modal.outerHeight();
		if (!_modalHeight) {
			_modalHeight = parseInt($modal.css('height')) + parseInt($modal.css('padding-top')) + parseInt($modal.css('padding-bottom'));
		}

		var _topPosition = (_windowHeight - _modalHeight) / 2
		$modal.parent().css({
			'top': _topPosition
		});
	};

	/**
	* TODO: The following two methods don't belong in this class. 
	* Move to a new class/location that makes more sense.
	**/

	// Set active view
	this.setActiveView = function($modal, viewName) {
		$modal.find('div.view').each(function(i) {
			var _$this = $(this);
			if (_$this.hasClass(viewName)) {
				_$this.show();
			} else {
				_$this.hide();
			}
		});
	};

	//
	this.setLoadingViewHeight = function($modal) {
		var _$loadingView = $modal.find('div.view.loading');
		var _$loadingContent = _$loadingView.find('div.loadingContent');
		var _height = $modal.outerHeight({ margin: true });

		//
		_$loadingView.show();

		// Set loading animation height
		_$loadingView.css('height', _height + 'px');
		_$loadingContent.css('padding-top', parseInt((_height / 2) - 40) + 'px');

		// Set loading animation opacity
		_$loadingView.css('opacity', '.85');
	};
};
