/**
 * Cobalt Elements for jQuery
 * cobalt - the main cobalt initializer.
 *
 * These methods are build on the jQuery and interface foundation to provider
 * client functionality to the Cobalt CMS system.
 *
 * Copyright (c) 2007 Scorpion Design, Inc.
 *
 */
$(document).ready(InitCobalt);

function InitCobalt()
{
	if ( window._flyout ) {
		// Set up side menu flyouts.
		$("[icobalt='CobaltControls.Controls.SideMenu'][_flyout='true']'").each(function(i){
			var menu = $(this),
				maxlevels = $.toInt(menu.attr('_maxlevels')),
				my = menu.attr('_my') || 'left top',
				at = menu.attr('_at') || 'right top';
			menu.find('[_pageid]')
					.each($.cms.flyout.setParent)
				.end()
				.flyout({my:my,at:at,maxlevels:maxlevels});
		});

		// And top menus.
		$("[icobalt='CobaltControls.Controls.TopMenu'][_flyout='true']").each(function(i){
			var menu = $(this),
				maxlevels = $.toInt(menu.attr('_maxlevels')),
				my = menu.attr('_my') || 'left top',
				at = menu.attr('_at') || 'left bottom';
			menu.find('[_pageid]')
					.each($.cms.flyout.setParent)
				.end()
				.flyout({my:my,at:at,maxlevels:maxlevels});
		});
	}

	// If we have an unknown timezone set, use the browser's time object to try and set the visitor's time zone.
	var m;
	if ( !/TimeZone/.test(document.cookie) ) {
		var offset = new Date().stdTimezoneOffset() / 60, tz;
		switch (offset) {
			case 10:
				tz = "Hawaiian Standard Time";
				break;
			case 9:
				tz = "Alaskan Standard Time";
				break;
			case 8:
				tz = "Pacific Standard Time";
				break;
			case 7:
				tz = "Mountain Standard Time";
				break;
			case 6:
				tz = "Central Standard Time";
				break;
			case 5:
				tz = "Eastern Standard Time";
				break;
			default:
				// Non-US time zone -- will use server local time zone.
				tz = "0";
				break;
		}
		document.cookie = [ 'Cobalt.TimeZone=', tz, '; path=/; domain=', encodeURIComponent(window.location.host) ].join("");
	}

	if ( window._fortran ) {
		$("input:hidden[id$='_FFD6']").val( new Date().getTime() );
	}

	// Let's wait a moment for the page to finish intializing before we load the flash movies.
	setTimeout(SetupFlashMovies,100);
}

// Make a page name into a url-friendly name.
$.cms.urlFriendly = function(name) {
	if (!name) {
		return "";
	} else {
		return (""+name).replace(/'+/g,'').replace(/\W+/g,'-');
	}
};

// Setup all flash movies on the page.
function SetupFlashMovies() {
	if (window._noflash) {
		return;
	} else {
		// Set up the hover images.
		$('.ihover').hoverImage();

		// Show the spotlight videos.
		if ( window._spotlight ) {
			$("div[icobalt='CobaltControls.Controls.Spotlight']").each(function(i){
				var div = $(this);
				var noplay = $.toBool(div.attr('_noplay'));
				if (!noplay)
					div.appendTo(document.body).css('display','block').embedswf();
			});
		}

		// Get the flash movies and flyouts on the page.
		var swf = $('form div.buildflash');
		var flyouts = window._flyout && $("[icobalt='CobaltControls.Controls.Flyout']");

		if ( window._nocontentflash ) {
			// Don't build flash/flyouts inside editable content zones.
			var nocontent = function(i){
				return $(this).parent().closest("[icobalt='CobaltControls.Controls.Content']").length === 0;
			};
			swf.filter(nocontent).embedswf();
			flyouts = flyouts && flyouts.filter(nocontent).each($.cms.flyout.setParent).parent();
		} else {
			swf.embedswf();
			flyouts = flyouts && flyouts.each($.cms.flyout.setParent).parent();
		}

		// Flyout elements are tricky.  If the immediate parent is a div, we need to go one level higher.
		if ( flyouts ) {
			flyouts.filter('div').parent().flyout();
			$.unique(flyouts.filter(':not(div)').closest('div,table')).flyout();
		}

		if ( window._mobilemenu ) {
			$("[icobalt='CobaltControls.Controls.MobileMenu']")
				.each($.cms.flyout.setParent)
				.parent()
					.removeClass('ifly')
					.addClass('imenuitem')
					.parent()
						.flyout({
							item: '.imenuitem',
							panel: 'div.imenu',
							hover: 'iover',
							right: 'iright',
							loading: 'iloading',
							my: 'right top',
							at: 'right bottom',
							mobile: true
						});
		}

		// Set up the site search.
		if ( window._sitesearch ) {
			$("[icobalt='CobaltControls.Controls.SiteSearch']").sitesearch();
		}

		// Set up a lightbox.
		if ( window._lightbox ) {
			$('.ilightbox').lightbox();
		}

		// Set up a scrolling datalist.
		if ( window._scroller && $.fn.scroller ) {
			$("div[icobalt='CobaltControls.Controls.ScrollingList']").scroller();
		}

		// And the quicklinks.
		if ( window._quicklinks ) {
			$("[icobalt='CobaltControls.Controls.QuickLinks']").each(function(i){
				var el = $(this);
				if ( !el.is('select') ) {
					el = el.find('select');
				}
				el.bind('change', function(e) {
					var href = $(this).val();
					if ( href ) {
						if ( !href.startsWith('http') && !href.startsWith('/') ) {
							href = "/" + href;
						}
						window.location.href = href;

						if ( e && e.preventDefault ) {
							e.preventDefault();
							e.stopPropagation();
							e.stopImmediatePropagation();
						}
						return false;
					}
				});
			});
		}

		// And any popups.
		if ( window._popup ) {
			$("a[icobalt='CobaltControls.Controls.Popup']").click(function(e){
				var link = $(this);
				$.popup({
					title: link.attr('_title') || null,
					url: $.getAjaxUrl( link.attr('href'), {Popup:true} ),
					width: $.toInt(link.attr('_width')) || 600,
					height: $.toInt(link.attr('_height')) || 400,
					noscroll: $.toBool(link.attr('_noscroll'))
				});
				e.preventDefault();
				e.stopPropagation();
				e.stopImmediatePropagation();
				return false;
			});
		}

		if ( window._videovault && $.cms.videopopup ) {
			$("a[icobalt='CobaltControls.Controls.VideoVault']").click(function(e){
				var link = $(this),				
					categories = link.attr('_categories'),
					video = link.attr('_video'),
					options = {
						categories: $.toIntArray(categories),
						video: $.toInt(video)
					},
					theme = link.attr('_theme');

				if ( theme ) {
					options.theme = theme;
				}

				$.cms.videopopup.prototype.activate(options);
				return false;
			});
		}

		if ( window._ajaxupload && $.cms.ajaxupload ) {
			$("div[icobalt='Cobalt.Controls.FileUpload']").ajaxupload();
		}
	}
}

// Clean up the crappy remove callback script when the page unloads.
function cleanupFlash() {
	__flash__removeCallback = function(instance, name){
		if (instance != null && name != null)
			instance[name] = null;
	};
}

// Simple video popup.
$.cms.popupvideo = function(file,streamer,autostart,width,height){
	var id = ('Player'+Math.random()).replace('.','');
	$('<div></div>')
		.dialog({
			modal: true,
			dialogClass: 'simple',
			width: width?width+20:443,
			height: height < 30 ? height+10 : 'auto',
			close: function(){ $(this).remove(); }
		})
		.append('<div></div>')
		.children()
			.css({width:width||423,height:height||245,margin:0,padding:0})
			.embedswf({
				swf: '/Shared/videovault/lt/player.swf',
				id: id,
				width: width||423,
				height: height||245,
				params: {
					flashvars: {
						streamer: streamer,
						file: file,
						autostart: autostart,
						skin: height < 30 ? null : "/Shared/videovault/lt/skins/glow.zip",
						'controlbar.position': height < 30 ? 'bottom' : 'over'
					}
				}
			});
};

// Cascade one dropdown to another.
$.fn.cascade = function() {
	return this.each(function(i){
		// Get the cascade property
		var input = $(this);
		var cascade = input.attr('_cascade');
		if ( cascade ) {
			// Find the cascading select.
			var child = $("form select[id$='_"+cascade+"']");

			// Build a list of child options.
			var items = [];
			child.children('option').each(function(i){
				var option = $(this);
				items.push({
					parent: option.attr('_parent'),
					value: option.attr('value'),
					label: option.html()
				});
			});
			child.data('items', items);

			// Bind the change event.
			input.data('cascade', child)
				.bind('change', function(e){
					// Get the cascading child.
					var input = $(this);
					var child = input.data('cascade');
					var items = child.data('items');
					var parent = input.val();

					// Build out the matching items.
					var sb = [];
					for ( var i=0; i<items.length; i++ ){
						var item = items[i];
						if ( !item.parent || item.parent == parent ) {
							sb.push('<option value="');
							sb.push(item.value);
							sb.push('">');
							sb.push(item.label);
							sb.push('</option>');
						}
					}

					// Set them.
					var val = child.val();
					child.html(sb.join('')).val(val||'');
				})
				.trigger('change');
		}
	});
};

// Display video tutorials.
$.widget( "cms.videotutorials", $.ui.dialog, {
	options: {
		nobridge: true,
		modal: true,
		width: 860,
		height: 590,
		title:'Video Tutorial: ',
		buttons: {
			"Close" : function(e, widget) {
				widget.close();
			}
		},
		open: function(e, data, widget) {
			widget._open.apply(widget, [e, data]);
		},
		videos: [],
		videoid: 0
	},

	// Open the video tutorials.
	activate: function(options) {
		if ( options && options.controls && ( !options.videos || !options.videos.length ) ) {
			options.videos = [];
			options.controls.each(function(i){
				options.videos.push( $(this).getRow() );
			});
			options.controls = null;
			delete options.controls;
		}

		// Make sure we have videos to show.
		if ( !options || !options.videos || !options.videos.length ) {
			$.alert('There are no video tutorials available here.');
			return null;
		}
		
		// Build the dialog box contents.
		var el = $('\
<div class="tt-main">\
	<div class="tt-player">\
		<div></div>\
	</div>\
	<a href="/Admin/Training.aspx" class="cms-btn-select right" style="float:right"><span>More Videos</span></a>\
	<div class="tt-videos">\
		<a class="tt-left" href="javascript:void(\'Prev\');">&nbsp;</a>\
		<span class="tt-start">Related Videos:</span>\
		<div class="tt-panel">\
			<div class="tt-scroller"></div>\
		</div>\
		<a class="tt-right" href="javascript:void(\'Next\');">&nbsp;</a>\
	</div>\
</div>');

		// Create the widget.
		var wz = $[this.namespace][this.widgetName];
		var instance = new wz( options, el[0] );
		return el;
	},

	// Create the wizard.
	_create: function() {
		// Run the base create.
		$.ui.dialog.prototype._create.apply( this, arguments );

		// Set up the title correctly.
		this.elements = {
			main: this.uiDialog.find('div.ui-dialog-main'),
			titlebar: this.uiDialog.find('div.ui-dialog-titlebar'),
			player: this.element.find('div.tt-player>div'),
			data: {
				title: this.element.find('div.tt-summary>h1'),
				summary: this.element.find('div.tt-summary>div')
			},
			videos: {
				left: this.element.find('a.tt-left'),
				panel: this.element.find('div.tt-panel'),
				scroller: this.element.find('div.tt-scroller'),
				right: this.element.find('a.tt-right')
			}
		};
		this.element.find('div.tt-videos').click( $.proxy(this._handleClick, this) );

		// Create the video.
		var start = this._getStart();
		this.elements.titlebar.children('span').html('Video Tutorial: ' + start.Title);

		// Create the video categories.
		this._createVideos();
	},

	// When the dialog is opened.
	_open: function() {
		// Do we have an overflow?
		var children = this.elements.videos.scroller.children();
		var panel = this.elements.videos.panel.width();
		var scroll = this.elements.videos.scroller.offset();
		var pos = children.eq( children.length-1 ).dimensions();
		this._overflow = pos.left+pos.width-scroll.left > panel;

		// Select the start video.
		var start = this._getStart();
		this._select( ( start && start.Index ) || 0 );
	},

	// Get the starting video.
	_getStart: function() {
		if ( this.options.videoid ) {
			for ( var i=0; i<this.options.videos.length; i++ ) {
				var video = this.options.videos[i];
				if ( video.VideoID === this.options.videoid ) {
					return video;
				}
			}
		}
		return this.options.videos[0];
	},

	// Create the list of videos.
	_createVideos: function() {
		var category = this.options.videos[0].CategoryName;
		var sb = [];
		for ( var i=0; i<this.options.videos.length; i++ ) {
			var video = this.options.videos[i];
			sb.push('<a class="tt-video" href="javascript:void(\'Play\');" _index="');
			sb.push(i);
			sb.push('">');
			sb.push(video.Title);
			sb.push('</a>');
		}
		this.elements.videos.scroller.html( sb.join("") );
		this._vposition = 0;
	},

	// Handle a click on a special button.
	_handleClick: function(e) {
		var link = $.getLinkTarget(e),
			href = link && link.attr('href'),
			m = href && /^javascript:(\w+)\('([^']+)'/i.exec(href),
			fn = m && m[1],
			action = m && m[2];

		switch ( action ) {
			case 'Next':
				this._advanceVideos(1);
				break;
			case 'Prev':
				this._advanceVideos(-1);
				break;
			case 'Play':
				var index = link.attr('_index');
				if ( index ) {
					this._select( $.toInt(index), true );
				}
				break;
			default:
				return;
		}

		return false;
	},

	// Select a specific video.
	_select: function(index, play) {
		// Update the preview data.
		var video = this.options.videos[index];
		this.elements.data.title.html( video.Title );
		this.elements.data.summary.html( video.Summary.replace( /\n/g, '<br>' ) );
		this.elements.videos.scroller
			.children()
				.removeClass('active')
				.eq( index )
					.addClass('active');

		// Load and play the next video.
		this.elements.player
			.embedswf({
				swf: '/Shared/videovault/lt/player.swf',
				id: ('Player'+Math.random()).replace(".",""),
				width: 800,
				height: 450,
				params: {
					flashvars: {
						file: video.Video,
						image: video.Thumbnail,
						skin: "/Shared/videovault/lt/skins/glow.zip",
						"controlbar.position": "over",
						plugins: 'hd',
						"hd.file": video.HDVideo,
						"hd.state" : false,
						"hd.fullscreen" : true,
						dock: false,
						autostart: play && !video.Thumbnail ? true : false
					}
				}
			},true);

		// Make sure the selected video is visible.
		this._vid = index;
		this._ensureVideos();
	},

	// Advance to the next video.
	_advanceVideos: function(amount, play) {
		var videos = this.elements.videos.scroller.children();

		// Advance to the next/prev category, wrapping as needed.
		var index = (this._vid||0) + amount;
		if ( index < 0 ) {
			index = videos.length-1;
		} else if ( index > videos.length-1 ) {
			index = 0;
		}

		// Activate the next category.
		this._select(index, play);
	},

	// Ensure that the active category is fully visible.
	_ensureVideos: function() {
		// No overflow, don't bother.
		if ( !this._overflow ) {
			return;
		}

		// Get the existing categories and the currently selected one.
		var videos = this.elements.videos.scroller.children();
		var vid = videos.filter('.active');
		if ( !videos.length || !vid.length ) {
			return;
		}

		// Get their positions.
		var first = videos.eq(this._vposition).offset().left;
		var index = videos.index(vid);
		var panel = this.elements.videos.panel.width();
		var pos = vid.dimensions();

		// If we're too far to the right.
		var shift = 0;
		while ( pos.left+pos.width-first > panel ) {
			shift++;
			first = videos.eq(this._vposition+shift).offset().left;
		}

		// If we're too far to the left.
		while ( pos.left < first ) {
			shift--;
			first = videos.eq(this._vposition+shift).offset().left;
		}

		// Adjust as needed.
		if ( shift != 0 ) {
			this._shiftVideos(shift);
		}
	},

	// Advance the video panel.
	_shiftVideos: function(amount) {
		// Get the existing videos.
		var videos = this.elements.videos.scroller.children();
		if ( !videos.length ) {
			return;
		}

		// And the next position.
		this._vposition += amount;
		if ( this._vposition >= videos.length ) {
			this._vposition = 0;
		} else if ( this._vposition < 0 ) {
			this._vposition = videos.length-1;
		}
		var vid = videos.eq(this._vposition);

		// Calcuate the offset.
		var parent = this.elements.videos.scroller.offset();
		var pos = vid.offset();
		var left = parent.left - pos.left;

		this.elements.videos.scroller.stop().animate( {marginLeft:left}, 400, $.proxy(this._ensureVideos, this) );
	},

	// Close the wizard.
	close: function() {
		// Call the default close event.
		$.ui.dialog.prototype.close.apply( this, arguments );

		// Then completely destroy the video vault instance.
		this.element.removeswf().remove();
	}
});

$.fn.onenter = function(){ return this; };

