(function($){

	$.fn.hcWindowShow = function(id)
	{
		var settings = this.data('settings');
		
		if (id != undefined)
		{	
			if (!parseInt(id))
			{
				id = $(settings.contentItems,settings.overlay).index($(id));
			}

			if (id < 0) id = 0;

			settings.current = id;

			// quick hide/show
			$(settings.contentItems,settings.overlay).hide().eq(id).show();
		}

		// callback
		if (settings.beforeShow) settings.beforeShow.call(this);

		var so, pos;

		if (settings.verticalAlign != 'none')
		{
			var vph = $(window).height(); // viewport height
			var oh = this.height(); // overlay height
			so = $(document).scrollTop(); // scroll offset
			pos = 0; // top position

			switch (settings.verticalAlign)
			{
				case 'top':
					pos = so;
					break;

				case 'bottom':
					pos = (vph-oh) + so;
					break;

				default: // middle
					pos = ((vph-oh)/2) + so;
					break;
			}

			// prevent off screen
			if (pos < 0) pos = 10;

			this.css('position','absolute');
			this.css('top',pos + settings.verticalOffset);
		}

		if (settings.horizontalAlign != 'none')
		{
			var vpw = $(window).width(); // viewport height
			var ow = this.width(); // overlay height
			so = $(document).scrollLeft(); // scroll offset
			pos = 0; // left position

			switch (settings.horizontalAlign)
			{
				case 'left':
					pos = so;
					break;

				case 'right':
					pos = (vpw-ow) + so;
					break;

				default: // center
					pos = ((vpw-ow)/2) + so;
					break;
			}

			this.css('position','absolute');
			this.css('left',pos + settings.horizontalOffset);
		}

		if (settings.screenOverlay) $(settings.screenOverlay).show();

		// callback (custom show)
		if (settings.show) settings.show.call(this);
		else this.show();

		// callback
		if (settings.afterShow) settings.afterShow.call(this);
	}
	
	$.fn.hcWindow = function(options)
	{
		return this.each(function()
		{
			// set options, overwriting defaults
			var settings = $.extend({}, $.fn.hcWindow.defaults, options);

			// self reference
			settings.overlay = $(this);

			if (settings.screenOverlayOpacity)
			{
				var z = parseInt($(settings.overlay).css('z-index'));
				settings.screenOverlay = $('<div></div>').css({height:'100%',width:'100%',position:'fixed',left:0,top:0,'z-index':z-1,opacity:settings.screenOverlayOpacity/100});
				$(settings.screenOverlay).hide().addClass(settings.screenOverlayClass).prependTo('body');
			}

			// keep settings specific to the overlay element
			$(this).data('settings',settings);

			// confirm all items are hidden
			$(settings.contentItems,settings.overlay).hide();

			// close link
			$(settings.closeLink,this).click(function(e)
			{
				e.preventDefault();

				// reference
				var overlay = $(settings.overlay);

				// callback
				if (settings.beforeClose) settings.beforeClose.call(overlay);

				if (settings.screenOverlay) $(settings.screenOverlay).hide();

				// callback (custom hide)
				if (settings.hide) settings.hide.call(overlay);
				else overlay.hide();

				// callback
				if (settings.afterClose) settings.afterClose.call(overlay);
			});

			// prev link
			$(settings.prevLink,this).click(function(e)
			{
				e.preventDefault();

				// reference
				var overlay = $(settings.overlay);

				// callback
				if (settings.beforePrev) settings.beforePrev.call(overlay);
				if (settings.beforePrevNext) settings.beforePrevNext.call(overlay);

				// calc prev index and check if at begining
				settings.current -= 1;
				if (settings.current < 0) settings.current = $(settings.contentItems,settings.overlay).length - 1;

				// callback (custom hide)
				var prev = $(settings.contentItems,settings.overlay).eq(settings.current);
				if (settings.hidePrev) settings.hidePrev.call(prev);
				else prev.hide();
				
				showHideContent();

				// callback
				if (settings.afterPrev) settings.afterPrev.call(overlay);
				if (settings.afterPrevNext) settings.afterPrevNext.call(overlay);
			});

			// next link
			$(settings.nextLink,this).click(function(e)
			{
				e.preventDefault();

				// reference
				var overlay = $(settings.overlay);

				// callback
				if (settings.beforeNext) settings.beforeNext.call(overlay);
				if (settings.beforePrevNext) settings.beforePrevNext.call(overlay);

				// calc next index and check if at ending
				settings.current += 1;
				if (settings.current >= $(settings.contentItems,settings.overlay).length) settings.current = 0;

				showHideContent();

				// callback
				if (settings.afterNext) settings.afterNext.call(overlay);
				if (settings.afterPrevNext) settings.afterPrevNext.call(overlay);
			});

			function showHideContent()
			{
				var from = $(settings.contentItems + ':visible',settings.overlay);
				var to = $(settings.contentItems,settings.overlay).eq(settings.current);

				// callback
				if (settings.beforeContentHide) settings.beforeContentHide.call(from);

				// callback (custom hide)
				if (settings.contentHide)
				{
					if ($.isFunction(settings.contentHide))
					{
						settings.contentHide.call(from,to);
					}
				}
				else
				{
					from.hide();
				}

				// callback
				if (settings.afterContentHide) settings.afterContentHide.call(from);
				if (settings.beforeContentShow) settings.beforeContentShow.call(to);

				// callback (custom show)
				if (settings.contentShow)
				{
					if ($.isFunction(settings.contentShow))
					{
						settings.contentShow.call(to,from);
					}
				}
				else
				{
					to.show();
				}

				// callback
				if (settings.afterContentShow) settings.afterContentShow.call(to);
			}
		});
	}

	$.fn.hcWindow.defaults =
	{
		// links inside the overlay
		prevLink : '.prev'
		, nextLink : '.next'
		, closeLink : '.close'
		, contentItems: '.item'

		, verticalAlign: 'auto' // none, top, middle, bottom, auto (middle)
		, verticalOffset: 0
		, horizontalAlign: 'auto' // none, left, center, right, auto (center)
		, horizontalOffset: 0

		, screenOverlayOpacity: 0
		, screenOverlayClass: 'hc-screen-overlay'

		// content before/after prev/next change callback
		, beforePrevNext: null
		, afterPrevNext: null

		// content before/after next change callback
		, beforeNext: null
		, afterNext: null

		// content before/after prev change callback
		, beforePrev: null
		, afterPrev: null

		// overlay before/after show callbacks
		, beforeShow: null
		, afterShow: null

		// overlay before/after hide callbacks
		, beforeHide: null
		, afterHide: null

		, beforeContentShow: null
		, afterContentShow: null
		
		, beforeContentHide: null
		, afterContentHide: null

		// window show/hide callbacks
		, show: null
		, hide: null

		// content show/hide callbacks
		// to bypass one of the below callbacks, set to true
		, contentShow: null
		, contentHide: null
	};

	// auto find/setup triggers
	$('[rel^=hcwindow], [rel^=hcwin]').click(function(e)
	{
		e.preventDefault();
		var parts = $(this).attr('rel').split('/');
		var win = parts[1];
		var idx = parts[2];
		$(win).hcWindowShow(idx);
	});

})(jQuery);