
function toggle_all_check_boxes( ele , val )
{
	if( val )
		$(ele + ' input:checkbox').attr('checked', 'checked');
	else
		$(ele + ' input:checkbox').removeAttr('checked');
}


function get(id) {
    return document.getElementById(id);
}



/*if(!Object.prototype.hashmerge) {
    Object.prototype.hashmerge = function(value) {
        extend(this, value)

        return this
    }
}*/

function toString(val) {
    if(val == undefined || val == null)
        return "<null>"

    var str = "{";

    var index = 0;
    for ( var name in val ) {
        var value = val[name];

        if(index++ > 0)
            str += ", "

        var valueString = (value == undefined || value == null) ?  "<null>" : value.toString();
        str += name + " = " + valueString
    }

    str += "}"

    return str;
}

/**
 * A bastard version of the Prototype version.
 */
Function.prototype.bind = function() {
    var __method = this;

    var sourceArguments = new Array();
    for (var i = 1; i < arguments.length; i++) {
        sourceArguments[i-1] = arguments[i];
    }

    var targetObject = arguments[0];

    return function() {
        var index = 0;
        var destinationArguments = new Array();
        for (var i = 0; i < sourceArguments.length; i++) {
            destinationArguments[index++] = sourceArguments[i];
        }
        for (var i = 0; i < arguments.length; i++) {
            destinationArguments[index++] = arguments[i];
        }

        return __method.apply(targetObject, destinationArguments);
    }
}

function toQueryString(vals) {
    var qString = "";
    for ( var key in vals ) {
        if(qString.length > 0) qString += "&";

        qString += (escape(key) + "=" + escape(vals[key]));
    }

    return qString;
}

function extend() {
    var destination = arguments[0];

    for ( var oi = 1; oi < arguments.length; oi++ ) {
        var source = arguments[oi];

        for ( var i in source ) {
            destination[i] = source[i]
        }
    }

    return destination;
}

function setCookie(c_name,value,expiredays)
{
	var exdate=new Date();
	if( expiredays != undefined )
		exdate.setDate(exdate.getDate()+expiredays);
	document.cookie= c_name + "=" + escape(value) + ";path=/" +  ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}

function getCookie(c_name)
{
	if (document.cookie.length>0)
	  {
	  c_start=document.cookie.indexOf(c_name + "=");
	  if (c_start!=-1)
	    {
	    c_start=c_start + c_name.length+1;
	    c_end=document.cookie.indexOf(";",c_start);
	    if (c_end==-1) c_end=document.cookie.length;
	    return unescape(document.cookie.substring(c_start,c_end));
	    }
	  }
	return "";
}

// http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/
function calculate_time_zone() {
	var rightNow = new Date();
	var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);  // jan 1st
	var june1 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0); // june 1st
	var temp = jan1.toGMTString();
	var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
	temp = june1.toGMTString();
	var june2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
	var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);
	var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60);
	var dst;
	if (std_time_offset == daylight_time_offset) {
		dst = "0"; // daylight savings time is NOT observed
	} else {
		// positive is southern, negative is northern hemisphere
		var hemisphere = std_time_offset - daylight_time_offset;
		if (hemisphere >= 0)
			std_time_offset = daylight_time_offset;
		dst = "1"; // daylight savings time is observed
	}
	
	return std_time_offset;
}

Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};

Object.extend = function(destination, source) {
  for (var property in source) {
	destination[property] = source[property];
  }
  return destination;
};





/*
	jQuery.hitch() -  Advanced scope manipulation for jQuery 
	version: 0.1, Peter Higgins (dante at dojotoolkit.org)

	(c) 2004-2009 The Dojo Foundation - adapted from `dojo.hitch`
	Either AFL/New BSD license, see: http://dojotoolkit.org/license 

	usage 1:
	
		var obj = {
			attr: "blah",
			func: function(){
				console.log(this.attr);
			}
		}
		
		// most useful example out of context, with setTimeout/Interval:
		setInterval($.hitch(obj, "func"), 2100) // call obj.func() in scope of obj
		setTimeout($.hitch(obj, function(){
			this.attr = "blargh";
			this.func();
		}), 2100);
	
	usage 2:
		
		// pseudo-class
		var Thinger = function(){
			this.foo = "bar";
			this.bar = function(event){
				// super generic function to reuse lots
				this.foo = $(event.target).attr("id");
			}
		}
		
		var mine = new Thinger();
		var yours = new Thinger();
		
		$(".foo").click($.hitch(mine, "bar"));
		$(mine).bind("bar", $.hitch(yours, "bar"));
		
*/
;(function($){

	$.hitch = function(scope, method){
		// summary: Create a function that will only ever execute in a given scope
		if(!method){method = scope;scope = null;}
		if(typeof method == "string"){
			scope = scope || window;
			if(!scope[method]){throw(['method not found']);}
			return function(){return scope[method].apply(scope, arguments || []);};
		}
		return !scope ? method : function(){return method.apply(scope, arguments || []);};
	}

})(jQuery);

function getDOM(id) {
    return document.getElementById(id);
}


/**
 * @author carl
 */

var Mixamo = {
	version: "1.0" ,
	template_path: "/js/" ,
	ERROR_MESSAGE: "Doh, there was a problem with our servers. Sorry about that. Our engineers have just been notified about the issue and will work on a fix ASAP. Please check back soon as these issues often only occur during routine site maintenence or updates and are usually quickly resolved.",
	error: function() {
        alert( Mixamo.ERROR_MESSAGE );
        //Mixamo.redirect_to( "/mystuff" );
    },
	valIsDebugMode: null,
	isDebugMode: function() {
		if (this.valIsDebugMode == null) {
			var strHref = document.location.href; 
			this.valIsDebugMode = ((strHref.indexOf("debug=T") > 0) || (strHref.indexOf("carl.mixamo.com") > 0) || (strHref.indexOf("qa.mixamo.com") > 0));
		}
		
		return this.valIsDebugMode;
	},
	
	/**
	 * Conditionally show or hide the specified DOM element
	 *
	 * @param element the element to show/hide
	 * @param show true to show, otherwise hide
	 */
	showHideElement: function (element, show) {
	    var ele = $(element);
		if (show )
	        ele.show();
	    else
	        ele.hide();
	} ,
	
	unique_div_id: 0,
	
	newUniqueDivId: function() {
		Mixamo.unique_div_id++;
		return "mixamoUDiv" + Mixamo.unique_div_id;
	} ,
	
	redirect_to: function(str) {
		window.location.href = str;
	},
	
	refresh_page: function() {
		window.location.href = window.location.href;
	},
	
	user_is_logged_in: function() {
		return($("#mixamo_loggedInUserId").length > 0 );
	},
	
	parse_uri: function(sourceUri){
	    var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"];
	    var uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri);
	    var uri = {};
	    
	    for(var i = 0; i < 10; i++){
	        uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
	    }
	    
	    // Always end directoryPath with a trailing backslash if a path was present in the source URI
	    // Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key
	    if(uri.directoryPath.length > 0){
	        uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
	    }
	    
	    return uri;
	},
	
	parse_query_string: function( q )
	{
		
		var keyValuePairs = {};
		var arr = q.split("&");
		if(q) {
			for(var i=0; i < arr.length; i++) {
				var v = arr[i].split("=");
				keyValuePairs[ v[0] ] = unescape(v[1]);
			}
		}
		
		return keyValuePairs;
	},
	
	jquery_encode: function(str) {
		return str.replace( ":" , "\\:" ).replace( "[" , "\\[").replace( "]" , "\\]")
	},
	
	alertObject: function( obj ) {
		var str = "Object: \n";
		for (var property in obj) {
			str += property + "=" + obj[property] + ",  ";
		  }
		alert(str);
	},
	
	getQueryString: function() {
		var h = document.location.href;
		var i = h.indexOf("?");
		if( i > 0)
			return h.substring( i + 1 );
		else
			return "";
	},
	
	getQueryStringParams: function() {
		return Mixamo.parse_query_string( Mixamo.getQueryString() );
	},
	
	
	applyNewCMSRevision: function() {
		$("div.browser_cms_segment").each( function() {
			var ele = $(this);
			var url = ele.attr("id").replace( "browser_cms_" );
			$.get( url , {} ,  function(data){
				alert( data );
				var start = '<div id="wrapper">';
				var end = '</div>';
				var txt = data.substring( data.indexOf(start) , data.lastIndexOf(end) );
				alert( txt );
				ele.html( txt );				
			} , "html"
			);
		});
	} ,
	
	random_string: function( string_length )
	{
		var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
		var randomstring = '';
		for (var i=0; i<string_length; i++) {
			var rnum = Math.floor(Math.random() * chars.length);
			randomstring += chars.substring(rnum,rnum+1);
		}
		return randomstring;
	},
	
	add_endpoints_to_slider: function( ele , startPointCall , endPointCall )
	{
		$(ele).prepend( "<div style='position:absolute;' class='mxmoSliderStartpoint'></div>");
		$(ele).append( "<div style='position:absolute;' class='mxmoSliderEndpoint'></div>");
		
		$( ".mxmoSliderStartpoint" , ele).click( function() {
			startPointCall.call(this);
		});
		
		$( ".mxmoSliderEndpoint" , ele).click( function() {
			endPointCall.call(this);
		});
		
	},
	
	disableSubmitButton: function( submit_form , txt) {
		return this.disableButton( $("input:submit", $(submit_form)) , txt);
	},
	
	enableSubmitButton: function( submit_form , txt) {
        return this.enableButton( $("input:submit", $(submit_form)) , txt);
    },
	
	disableButton: function( btn , txt )
	{
		var btn = $(btn);
		btn.attr("disabled" , "disabled");
		btn.addClass("submitBtnDisabled");
		if( txt )
          btn.val( txt );
		return true;
	},
	
	enableButton: function( btn , txt) {
		var btn = $(btn);
		btn.removeAttr("disabled" );
		btn.removeClass("submitBtnDisabled");
		if( txt )
          btn.val( txt );
		return true;		
	},
	
	replace: function( )
	{
		var url = arguments[0];
		for (var i = 1; i < arguments.length; i++) {
			url = url.replace("*" + (i - 1).toString() + "*", arguments[i]);
		}
		return url;
	},
	
	prompt: function( title , promptText, buttonName , callback ) {
			if( $("#mixDialogPrompt").length == 0 ) {
				$('<div id="mixDialogPrompt" title="Prompt"><div class="contents"><span id="mixPromptText">Value:</span> <input type="text" id="mixPromptVal" maxlength="50" size="20" /></div></div>').dialog({ 
					modal: true , 
					height: 125 ,
					resizable: false,
					position: [ "center" , "center"],
					autoOpen: false
				});
			}
			var ele = $("#mixDialogPrompt");
			ele.dialog('option' , 'title' , title);
			$("span#mixPromptText" , ele).text( promptText );
			$('input#mixPromptVal').val('');
			var btns = {};
			btns[buttonName] = function() { 
						var pval = $('input#mixPromptVal').val();
						if (callback.call(this,pval)) {
							$("#mixDialogPrompt").dialog("close");
						}
					};
			ele.dialog( 'option' , 'buttons' , btns );
			ele.dialog("open");
		},
		
	alert: function(  message , callback , options)
	{
		if( options == undefined )
			options = {};
		
		var title = "Alert!";
		var buttonName = "OK";
		if( options.title != undefined)
			title = options.title;
		
		if( options.buttonName != undefined)
			buttonName = options.buttonName;
		
		if( $("#mixDialogAlert").length == 0 ) {
				$('<div id="mixDialogAlert" title="Alert"><div class="contents"></div></div>').dialog({ 
					modal: true , 
					height: ( options.height ? options.height : 125 ) ,
					width: ( options.width ? options.width : 300 ) ,
					resizable: false,
					draggable: false,
					position: (options.position != undefined ? options.position : [ "center" , "center"]),
					autoOpen: false
				});
			}
			var ele = $("#mixDialogAlert");
			ele.dialog('option' , 'title' , title);
			$("div.contents" , ele).html( message );
			var btns = {};
			btns[buttonName] = function() { 
				$("#mixDialogAlert").dialog("close");
			};
			ele.one('dialogclose', function(event, ui) {
				
				if( callback != undefined )
					callback.call(this);
			});
			ele.dialog( 'option' , 'buttons' , btns );
			ele.dialog("open");
	},
	
	help: function(  message , callback , options)
	{
		if( options == undefined )
			options = {};
		
		var title = "Info";
		var buttonName = "OK";
		if( options.title != undefined)
			title = options.title;
		
		if( options.buttonName != undefined)
			buttonName = options.buttonName;
		
		if( $("#mixDialogHelp").length == 0 ) {
				$('<div id="mixDialogHelp" title="Info"><div class="contents"></div></div>').dialog({ 
					modal: true , 
					height: ( options.height ? options.height : 275 ) ,
					width: ( options.width ? options.width : 400 ) ,
					resizable: false,
					draggable: false,
					position: (options.position != undefined ? options.position : [ "center" , "center"]),
					autoOpen: false
				});
			}
			var ele = $("#mixDialogHelp");
			ele.dialog('option' , 'title' , title);
			$("div.contents" , ele).html( message );
			var btns = {};
			btns[buttonName] = function() { 
				$("#mixDialogHelp").dialog("close");
			};
			ele.one('dialogclose', function(event, ui) {
				if( callback != undefined )
					callback.call(this);
			});
			ele.dialog( 'option' , 'buttons' , btns );
			ele.dialog("open");
	},
	
	//Mixamo.confirm( "Blah" , "Would you like to play house?" , "Yes" , "No" ,function() { Mixamo.console.info( this ) } )
	confirm: function( title , message , okButtonName, cancelButtonName , callback , options)
	{
		if( options == undefined )
			options = {};
			
		if( $("#mixDialogAlert").length == 0 ) {
				$('<div id="mixDialogAlert" title="Alert"><div class="contents"></div></div>').dialog({ 
					modal: true , 
					height: ( options.height ? options.height : 125 ) ,
										width: ( options.width ? options.width : 300 ) ,
					resizable: false,
					draggable: false,
					position: [ "center" , "center"],
					autoOpen: false
				});
			}
			var ele = $("#mixDialogAlert");
			ele.dialog('option' , 'title' , title);
			$("div.contents" , ele).html( message );
			var btns = {};
			btns[okButtonName] = function() { 
				callback.call(this , true);
				$("#mixDialogAlert").dialog("close");
			};
			
			btns[cancelButtonName] = function() { 
				callback.call(this , false);
				$("#mixDialogAlert").dialog("close");
			};
			ele.one('dialogclose', function(event, ui) {
				if (event.originalEvent != undefined) {
					callback.call(this, false);
				}
			});
			ele.dialog( 'option' , 'buttons' , btns );
			ele.dialog("open");
	},
	
	thumbnail: function( motion_name , description , sliders , n_frames , extra_text ) {
		if( $("#mixDialogThumbnail").length == 0 ) {
			$('<div id="mixDialogThumbnail" ><div class="contents" style="position: relative;">' + 
			'<div style="position: absolute; top: 10px; left: 10px;width: 266px; height: 329px; padding: 0;"><img width="266" height="329" src="/site-content/thumbnails/motion_315.gif" id="mixDialogThumb_Image" /></div>' +
			'<div style="position: absolute; top: 10px; left: 290px;width: 150px; height: 329px;"><div id="mixDialogThumb_General"></div><div id="mixDialogThumb_ImageSpecs"></div></div>' +
			'<div class="thumbImagesSelector" style="position: absolute; top: 349px; left: 10px;">' +
			/*'<img class="selected thumbImage" width="76" height="94" id="mixDialogThumb_Image1" src="/site-content/thumbnails/motion_315-first.gif"  />' + 
			'<img class="thumbImage" width="76" height="94" id="mixDialogThumb_Image2" src="/site-content/thumbnails/motion_315-first.gif"  />' + 
			'<img class="thumbImage" width="76" height="94" id="mixDialogThumb_Image3" src="/site-content/thumbnails/motion_315-first.gif" />' + */
			'</div>' +
			  '</div></div>').dialog({ 
				modal: true , 
				height: 400,
				minHeight: 400 ,
				width: 500,
				resizable: false,
				position: [ "center" , "center"],
				autoOpen: false , 
				title: null,
				draggable: false ,
				buttons: {
					"Close" : function() {
						$("#mixDialogThumbnail").dialog("close");
					} 
				}
			});
			
		}
		
		var sliders_str = "";
		$(sliders).each( function() {
			sliders_str += "<li>" + this.name + "</li>";
		});
		sliders_str = "<ul>" + sliders_str + "</ul>"
		$("#mixDialogThumb_General").html( "<div class='thumbMotionName'>" + motion_name + "</div><div class='thumbMotionDesc'>" + description + "</div>" + 
			"<div class='thumbSliders'>Customize<br/>" + sliders_str + "</div><div class='thumbFrames'>" + n_frames  + " Frames</div><div class='thumbExtraText'>" + extra_text + "</div>")
		/*
		$("#mixDialogThumb_Image1")[0].onclick = function() {
			$("#mixDialogThumbnail img.thumbImage").removeClass("selected");
			$("#mixDialogThumb_Image1").addClass("selected");
		};
		
		$("#mixDialogThumb_Image2")[0].onclick = function() {
			$("#mixDialogThumbnail img.thumbImage").removeClass("selected");
			$("#mixDialogThumb_Image2").addClass("selected");				
		};
		
		$("#mixDialogThumb_Image3")[0].onclick = function() {
			$("#mixDialogThumbnail img.thumbImage").removeClass("selected");
			$("#mixDialogThumb_Image3").addClass("selected");
		};*/
		Mixamo.console.info("thumbnail")
		var ele = $("#mixDialogThumbnail");
		$( ele.parent() ).addClass( "ui-dialog-MixamoThumbnail");
		ele.dialog("open");
	},
	
	thumbnail_show_zoom: function( thumbnail_ele )
	{
		thumbnail_ele = $(thumbnail_ele);
		var htmlBody = thumbnail_ele.children('input.thumbPopupContents').val();
		
		var dialogWidth = 225;
		if( $("#mixDialogThumbnailZoom").length == 0 ) {
			$('<div id="mixDialogThumbnailZoom"><div class="contents" style="position: relative;">' + 
				htmlBody +
			  '</div></div>').dialog({ 
				modal: false , 
				height: 305,
				minHeight: 305 ,
				width: dialogWidth,
				resizable: false,
				position: [ "center" , "center"],
				autoOpen: false , 
				title: null,
				draggable: false ,
				buttons: {
				}
			});	
		}
		
		var ele = $("#mixDialogThumbnailZoom");
		$( ele.parent() ).addClass( "ui-dialog-MixamoThumbnailZoom");
		$("div.contents" , ele ).html( htmlBody );
		var thumbnail_pos = thumbnail_ele.offset();
		if ( (thumbnail_pos.left + 81 + dialogWidth) < $(document).width()) {
			ele.dialog("option", "position", [thumbnail_pos.left + 86, thumbnail_pos.top - $(document).scrollTop() -30]);
		} else {
			ele.dialog("option", "position", [thumbnail_pos.left - dialogWidth - 6, thumbnail_pos.top - $(document).scrollTop() -30 ]);			
		}
		$( "a.thumbnail" , thumbnail_ele ).addClass("thumbnail-ManualHover");
		ele.dialog("open");
	},
	
	thumbnail_hide_zoom: function() {
		$( "a.thumbnail" ).removeClass("thumbnail-ManualHover");
		if ($("#mixDialogThumbnailZoom").length > 0) {
			$("#mixDialogThumbnailZoom").dialog("close");
		}
	},
	
	thumbnail_load_events: function() {
		$("div.mini-motion-section div.thumbnail div.thumbnailMouseoverRegion").mouseenter( function() {
			Mixamo.thumbnail_show_zoom( $(this).parent() );
		}).mouseleave( function() {
			Mixamo.thumbnail_hide_zoom();
		}).show();
		$("div.mini-motion-section div.priceVariationHack").mouseenter( function() {
			var e = $(this);
			e.hide();
			$("div.priceVariationDescHack" , e.parent() ).show();
			
		});
		$("div.mini-motion-section div.priceVariationDescHack").mouseleave( function() {
            var e = $(this);
            e.hide();
			$("div.priceVariationHack" , e.parent() ).show();
        });
	},

	
	
  escapeHTML: function(str) {
    return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return str.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
	/*, create_bindable_object: function(obj)
	{
		obj.changedVarialbes = {};
		  for (var property in obj) {
		  	
			obj["_" + property] = obj[property];
			obj.changedVarialbes[property] = false;
			obj[property] = function(val) {
				var ownName = arguments.callee.toString();
	            ownName = ownName.substr('function '.length);
	            ownName = ownName.substr(0, ownName.indexOf('('));				
				if( val != undefined )
				{
					this.changedVariables[ownName] = true;
					this["_" + ownName] = val;
				}
				return this["_" + ownName];			
			}
			
			destination[property] = source[property];
		  }
		  return destination;
	}*/
};


Mixamo.Array = {
	contains: function(arr , value) {
        for ( var index = 0; index < arr.length; index++ ) {
            if(arr[index] == value)
                return true;
        }

        return false;
    },
	
	select: function( arr , func) {
		var new_arr = [];
		for( var i=0 ; i < arr.length; i++ )
		{
			if( func.call(arr[i]) )
				new_arr.push(arr[i]);
		}
		return new_arr;
	},
	
	select_first: function( arr , func ) {
		for( var i=0 ; i < arr.length; i++ )
		{
			if( func.call(arr[i]) )
				return arr[i];
		}
		return null;
	} , 
	
	collect: function( arr , func ){
		var new_arr = [];
		for( var i=0 ; i < arr.length; i++ )
		{
			new_arr.push( func.call(arr[i]) );
		}
		return new_arr;
	}
	
}

Mixamo.BoundDataModule = {
	broadcast: function(  ignore_obj ) {
		Mixamo.console.info( "broadcast events! " );
		for (i in this.bound_objs)
		{
			var x = this.bound_objs[i];
			if( x != ignore_obj && x.loaded )
				x.bind_data();
		}
	},
	
	bind_to: function( obj ) {
		Mixamo.console.info( "set up bind to: " + obj.toString() );
		if( this.bound_objs == undefined )
			this.bound_objs = [];
		this.bound_objs.push( obj );
	}
};


Mixamo.Control = function(name)
{
	this.loaded = false;
	this.ele = null;
	this.template_render = EJSTemplates[name];
};

Mixamo.Control.prototype = {
	
	bind_events: function() {
		throw "Error you must override the bind events method!";
	},
	
	bind_data: function() {
		throw "Error you must override the bind data method!";
	},
	
	load: function( e  )
	{
		if (typeof e == "string") {
			this.ele = $("#" + e);
		} else {
			this.ele = $(e);
			
		}
		this.ele.get(0).innerHTML = this.template_render; 
		this.loaded = true;
		this.bind_events();
		this.bind_data();
	}, 
	
	/*
	before_unload: function() {
	},
	
	unload: function( )
	{
		this.before_unload();
		this.ele.html("");
		this.ele = null;
		this.loaded = false;
	},
	
	reload: function() {
	} ,
	*/ 
	
	append_div: function( query ) {
		var i = Mixamo.newUniqueDivId();
		var eleToUse = ( query == undefined ? this.ele : $( query , this.ele) );
		eleToUse.append(  "<div id='" + i + "'></div>");
		return i;
	} ,
	
	prepend_div: function( query ) {
		var i = Mixamo.newUniqueDivId();
		var eleToUse = ( query == undefined ? this.ele : $( query , this.ele) );
        eleToUse.prepend(  "<div id='" + i + "'></div>");
		return i;
	},
	
	
	get: function( selector ) {
		return $( selector , this.ele );
	} , 
	
	disable: function() {
		this.ele.hide();
	},
	
	enable: function() {
		this.ele.show();
	}
};

Mixamo.SelectBoxAndInput = function( input_id , arrOptions ){
	var input_ele = $("input#" + input_id );
	var input_id = input_id;
	var a_ele = $("<img style='width: 22px; height: 22px; font-decoration: none;cursor: pointer;' src='/images/selectboxoptions.png' align='absbottom' />");
	var options_ele = $('<div class="Mixamo_SelectBoxAndInput_options" style="display: none; position: absolute;"><ul></ul></div>');
	input_ele.css({
		'width': 50,
		'height': 18,
		'padding': "2px 5px 0px 5px",
		'margin': "0px" ,
		'border': "1px solid #CCCCCC"
	});
	input_ele.after(a_ele);
	
	a_ele.click( function() {
		$(options_ele).toggle();
		options_ele.css( { 
			'top' : input_ele.position().top + 22 , 
			'left': input_ele.position().left ,
			'width': 82} ); 
	} );
	
	a_ele.after(options_ele);
	
	/*input_ele.blur( function() {
		$(options_ele).hide();
	});*/
	
	$.each( arrOptions , function(index , value)
	{
		var liEle = $("<li>" + value  + "</li>");
		$( "ul" , options_ele).append( liEle );
		liEle.click( function() {
			input_ele.val( $(this).html() );
			options_ele.hide();
			return false;
		});
	});
}


Mixamo.Uploader = {
	displayFinalizeSkeleton: function( )
	{
		this.hideLoading();
		$('div#uploadSkeleton_div').hide();
		$("input.redirect").val( $('#prev_redir').val() );
	} ,
	
	displayErrorMessage: function( msg )
	{
		this.hideLoading();
		$('div#uploadSkeletonErrorMessage').html(msg);
		$('div#uploadSkeletonSuccessMessage').html("");
	} , 
	
	displayLoading: function() {
		$('#uploadSkeletonLoading').show();
	} , 
	
	hideLoading: function()
	{
		$('#uploadSkeletonLoading').hide();
	}, 
	
	displaySuccess: function( msg ) {
		this.hideLoading();
		$('div#uploadSkeletonErrorMessage').html("");
		$('div#uploadSkeletonSuccessMessage').html(msg);
		var fEle = $('div#uploadSkeletonSuccessMessage span.finalizingMessage');
		if( fEle.length > 0 )
		{
			fEle.pulse( {opacity: [0.05,1]} , 750, 1000 , "linear");
		}
	}
}




Mixamo.console = {
	mixamoDebugWindow: null,
	mixamoDebugWindowOn: null,
	mixamoDebugConsoleOn: null,
	
	
	info: function(str) {
		
		if( Mixamo.console.mixamoDebugWindowOn == null)
			Mixamo.console.mixamoDebugWindowOn = (document.location.href.indexOf("debugwindow=T") > 0);
		if( Mixamo.console.mixamoDebugConsoleOn == null)
			Mixamo.console.mixamoDebugConsoleOn = Mixamo.isDebugMode();
		
		if( Mixamo.console.mixamoDebugWindowOn )
		{
			if (Mixamo.console.mixamoDebugWindow == null) {
				Mixamo.console.mixamoDebugWindow = $("div#mixamoDebugWindow");
				if (Mixamo.console.mixamoDebugWindow.length > 0)
					Mixamo.console.mixamoDebugWindow.show();
			}
			if (Mixamo.console.mixamoDebugWindow.length > 0) {
				var e = $("<div><strong>&gt;</strong>&nbsp;<span></span></div>");
				$("span" , e).text( str );
				Mixamo.console.mixamoDebugWindow.prepend(e);
			}
		} else {
			if( Mixamo.console.mixamoDebugConsoleOn) {
				try {
					console.info(str);
				} 
				catch (e) {
					
				}
				
			}
		}
	},
	
	error: function(str) {
		alert( "There was an error on mixamo.com. Please report this message to support@mixamo.com! Error: " + str);
	}
	
}

//
// JS Cookie Handling Methods
// thanks http://www.quirksmode.org/js/cookies.html
//

Mixamo.createCookie = function(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

Mixamo.readCookie = function(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

Mixamo.eraseCookie = function (name) {
	Mixamo.createCookie(name,"",-1);
}





var mxmoQueueHsh = {};
var mxmoProcessingHsh = {};
Mixamo.queueFunction = function( name , func , max_size) {
	if( max_size == undefined )
	{
		max_size = -1;
	}
	
	if (!mxmoQueueHsh[name]) {
		mxmoQueueHsh[name] = new Mixamo.Queue(max_size);
		mxmoProcessingHsh[name] = false;
	}
	mxmoQueueHsh[name].enqueue( func );
	if (!mxmoProcessingHsh[name]) {
		mxmoProcessingHsh[name] = true;
		mxmoQueueHsh[name].dequeue().call(name);
	}
}

Mixamo.dequeueFunction = function( name )
{
	var func = mxmoQueueHsh[name].dequeue();
	if( func != undefined) {
		func.call(name);
	} else {
		mxmoProcessingHsh[name] = false;
	}
}

function randRange( left, right )
{
	return left + Math.floor( Math.random() * ( right - left) );	
}

Mixamo.Bubbles = {	
	start: function(TIME_FOR_INTERVAL , TIME_TO_ANIMATE) {
		setInterval( "Mixamo.Bubbles.update(" + TIME_TO_ANIMATE + ")"  , TIME_FOR_INTERVAL  );
	} ,
	
	update: function( TIME_TO_ANIMATE ) {
			$("div.bg-bubble").each( function() {
				var ele = $(this);
				var randOpacity = randRange( 5,70 ) / 100;
				var randLeft = -randRange( 75,200 );
				
				
				if( ele.hasClass("left-bubble") )
				{
					$(this).animate( {  
						top: randRange( 50,300 ) , 
						left: randLeft} , {
						queue: false,
						duration: TIME_TO_ANIMATE
					} ).fadeTo( TIME_TO_ANIMATE, randOpacity);
				} 
				else if( ele.hasClass( "right-bubble") )
				{
					$(this).animate( { 
						top: randRange( 100,200 ) , 
						right: randLeft} , 
						{
						queue: false,
						duration: TIME_TO_ANIMATE
					} ).fadeTo( TIME_TO_ANIMATE, randOpacity);
				}
				else
				{
					$(this).animate( {top: randRange( 400,600 ) , right: randLeft} , {
						queue: false,
						duration: TIME_TO_ANIMATE
					} ).fadeTo( TIME_TO_ANIMATE, randOpacity);	
				}
				/*
				var randSignLeft = Math.random() > 0.5 ? "+=" : "-=";
				var randSignTop = Math.random() > 0.5 ? "+=" : "-="
				var randTime = Math.floor( Math.random() * 3000 );
				*/
				
			});
		}
}

Mixamo.ApplicationSidebar = {
	APP_SIDEBAR_OPEN_POS: 965,
	APP_SIDEBAR_CLOSED_POS: 795,
	load: function(visible) {
		var ele = $("#application-sidebar");
		if (visible) {
			ele.css("left", this.APP_SIDEBAR_OPEN_POS + "px");
			$("div.showHide" , ele).removeClass("showHide-Hidden");
		}
		else {
			ele.css("left", this.APP_SIDEBAR_CLOSED_POS + "px");
			$("div.showHide" , ele).addClass("showHide-Hidden");
		}
		ele.css("visibility" , "visible");
		var mainWindow = $("#layout-middle-window");
		if( mainWindow.height() < (ele.height() + 50) )
		{
			mainWindow.css("min-height" , ele.height() + 50);
		}
	},
	toggle: function() {
		var ele = $("#application-sidebar");
		if (ele.position().left == this.APP_SIDEBAR_OPEN_POS) {
			ele.animate({
				left: this.APP_SIDEBAR_CLOSED_POS
			});
			$("div.showHide" , ele).addClass("showHide-Hidden");
			
			$.post( "/users/hide_sidebar", {dummyvar: "1"} , function() {} , "json");
		}
		else {
			ele.animate({
				left: this.APP_SIDEBAR_OPEN_POS
			});
			$("div.showHide" , ele).removeClass("showHide-Hidden");
			
			$.post( "/users/show_sidebar" , {dummyvar: "1"} , function() {} , "json");
		}			
		return false;
	},
	complete_task: function(task) {
		$("#sidebar-task-" + task ).addClass("todoComplete");
	}
}


Mixamo.BottomDownloader = {
	always_reload : false,
	
	layout_fixed_height: 150,
	header_fixed_max_width: 578,
	header_fixed_min_width: 150,
    
	load: function() {
		$("#bottomDownloadHeader").click( function() {
			var ele = $("#bottomDownloadContent");
            if (!ele.is(':visible')) {
				Mixamo.BottomDownloader.open({
					reload: false
				});
			} else {
				Mixamo.BottomDownloader.close();
			}
        } );
		
	},
	
	open: function( options ) {
	   
	   if( options == undefined )
		  options = {reload: false, alert: false};
	   var ele = $("#bottomDownloadContent");
        
	   if( ele.html() == "" || options.reload ||  Mixamo.BottomDownloader.always_reload ) {
          ele.html( "Loading ... " );
          $.get( "/userhome/recent_purchased_clips" , { sidx: 'date' , sord: 'desc'} , function( data ) {
             ele.html( data );
             
             Mixamo.BottomDownloader.load_motions();
             
            $("#miniDownloadSubmit").click(function() {
                var ele2 = $("div#miniPurchasedClips div.item-selected");
                if( ele2.length == 0 ) {
                    alert( 'Please first select the motion you want to download!');
                    return false;
                } else {
					if (ele2.hasClass("item-new")) {
						ele2.removeClass("item-new").addClass("item-old");
						var dlCounterEle = $("#totalNumOfNewDownloads span");
						var numOfNewDls = dlCounterEle.text();
						dlCounterEle.text((numOfNewDls * 1) - 1);
					}
					$("#mini_request_skin").val( $(".input_request_skin" , ele2).val() );
                    $("#mini_skin_variant").val( $(".input_skin_variant" , ele2).val() );
                    $("#mini_selectedUserClipId").val( $(".input_selectedUserClipId" ,ele2).val() );
                    return true;
                }
            });
			
			$("#miniDownloadCustomize").click( function() {
				var ele2 = $("div#miniPurchasedClips div.item-selected");
                if (ele2.length == 0) {
					alert('Please first select the motion you want to customize!');
				} else {
					Mixamo.redirect_to( "/editor/clip/" + $(".input_selectedUserClipId" ,ele2).val() );
				}
				return false;
			});
			
			Mixamo.BottomDownloader.resize_overlay();
			
          } , "html" );
		  
       }
	   if( Mixamo.Unity )
            Mixamo.Unity.Hide( "downloader" );
	   if (options.alert) {
	   	$("#bottomDownloaderSAContent").html(options.alert);
		$("#bottomDownloaderSpecialAlert").show();
	   }
	   Mixamo.BottomDownloader.resize_overlay();
       $("#bottomDownloaderOverlay").show();
	   var win_ele = $(window);
	   win_ele.bind( "resize" , Mixamo.BottomDownloader.resize_overlay );
	   $("#bottomDownloadHeader").css( { width: Mixamo.BottomDownloader.header_fixed_max_width } );
	   ele.show();
	   $("#bottomDownloaderMinMaxIcon").text("[-]");
	   
	   Mixamo.BottomDownloader.update_thumbnails();
	},
	
	load_motions: function() {
		
	     $("div#miniPurchasedClips div.item").click( function() {
            $("div#miniPurchasedClips div.item").removeClass("item-selected");
            $(this).addClass("item-selected");

            $("select#mini_formatselectbox").val($(this).attr("default_download_format"));

            var container = this
            $.each(["bvh_bip", "bvh_secondlife"], function(index, download_code) {
                var element = $("select#mini_formatselectbox option[value=" + download_code + "]")

                if($("input.conditionalDownloadFormat[name=" + download_code + "]", container).length == 1)
                    element.removeAttr("disabled")
                else
                    element.attr("disabled", "disabled")
            })
         });
        
        var num = $("div#miniPurchasedClips .purchasedClipsTotal").text() * 1;
        if( num > 0 ) {
         $("#totalNumOfNewDownloads span").text( num.toString() );
         $("#totalNumDownloadsContainer").addClass("tndcNew");
        } else {
            $("#totalNumDownloadsContainer").removeClass("tndcNew");
        }
		
		$("div#miniPurchasedClips .purchasedClipsMore").click( function() {
			var thisEle = $(this);
			$(".purchasedClipsMoreLoading" , thisEle).show();
			$.get( "/userhome/more_recent_purchased_clips" , {limit: $(".nextRequestClipsLimit" , thisEle).text() }, function( data ) {
				$("div#miniPurchasedClips").html( data );
				Mixamo.BottomDownloader.load_motions();
			} , "html");
		});
		
		if( !Mixamo.BottomDownloader.thumbnailsAreUpToDate()  )
		  Mixamo.BottomDownloader.always_reload = true;
		else
		  Mixamo.BottomDownloader.always_reload = false;
	},
	
	close: function() {
		var ele = $("#bottomDownloadContent");
		if( Mixamo.Unity )
            Mixamo.Unity.Show( "downloader" );
           ele.hide();
		$("#bottomDownloaderOverlay").hide();
		$("#bottomDownloaderSpecialAlert").hide();
		$(window).unbind( "resize" , Mixamo.BottomDownloader.resize_overlay );
		$("#bottomDownloadHeader").css( { width: Mixamo.BottomDownloader.header_fixed_min_width } );
		$("#bottomDownloaderMinMaxIcon").text("[+]");
		
		clearTimeout( Mixamo.BottomDownloader.thumbnailUpdateTO );
	},
	
	resize_overlay: function() {
		var h = $(window).height();
		var w = $(window).width();
		$("#bottomDownloaderOverlay").css( {
			width: w,
			height: h
		});
		
		$("#miniPurchasedClips").css( { height: h - Mixamo.BottomDownloader.layout_fixed_height } );
	},
	
	thumbnailsAreUpToDate: function() {
		return( $('#miniPurchasedClips .thumbnail-firstonly-generated , #miniPurchasedClips .thumbnail-isprocessing').length == 0 );
	},
	
	update_thumbnails: function() {
	   	Mixamo.BottomDownloader.thumbnailUpdateTO = setTimeout(function(){
	   	
	   		var id_arr = $.makeArray( $("#miniPurchasedClips .thumbnail-firstonly-generated , #miniPurchasedClips .thumbnail-isprocessing").map(function(a) {
	   			return $(this).parent().attr("id").replace("clip_thumb_container_", "");
	   		}));
			
			if (id_arr.length > 0) {
				$.ajax({
					url: "/userhome/update_clip_thumbnails",
					data: {
						ids: id_arr.join(",")
					},
					dataType: "script",
					complete: function(){
						if (Mixamo && Mixamo.BottomDownloader) {
							Mixamo.BottomDownloader.update_thumbnails();
						}
					}
				});
			}
	   		
	   	}, 10000);
	}
	
};



Mixamo.Queue = function( max_size ){

  // the list of elements, initialised to the empty array
  var queue = [];
  var self = this;
  // the amount of space at the front of the queue, initialised to zero
  var queueSpace = 0;
  
  var queueMaxSize = (max_size == undefined ? -1 : max_size);

  this.getSize = function(){
    // return the number of elements in the queue
    return queue.length - queueSpace;
  }

  this.isEmpty = function(){
    return self.getSize() == 0;
  }
  
  this.clear = function() {
  	queue = [];
  }
  
  this.rawdata = function() {
  	return queue;
  }

  this.enqueue = function(element){
  	var v = null;
	if (max_size == self.getSize()) {
		v = self.dequeue();
	}
	queue.push(element);
	return v;
  }

  this.dequeue = function(){
    var element = undefined;
    if (queue.length){
      // fetch the oldest element in the queue
      element = queue[queueSpace];
      // update the amount of space and check whether a shift should occur
      if (++queueSpace * 2 >= queue.length){
        // set the queue equal to the non-empty portion of the queue
        queue = queue.slice(queueSpace);
        // reset the amount of space at the front of the queue
        queueSpace=0;
      }
    }

    // return the removed element
    return element;
  }

  this.peek = function(){
    // initialise the element to return to be undefined
    var element = undefined;
    // if the queue is not element then fetch the oldest element in the queue
    if (queue.length) element = queue[queueSpace];
    // return the oldest element
    return element;
  }

}

Mixamo.VideoPlayer = function( obj_id ) {
	this.id = obj_id;
}

Mixamo.Video = {
	playerVolumeCookies: {},
	players: {},
	playerCount: 0,
	defaultOptions: {
		backcolor: "dadada",
		screencolor: "000000",
		playerready: "playerReadyCallbackio"
	},
	
	defaultVolume: "100",
	defaultMute: false ,
	
	volumeIsUserControlled: function( player_id ) {
		var c = getCookie(this.playerVolumeCookies[player_id])
		return( c != undefined && c != "" );
	},
	
	getMute: function( player_id ) {
		var cook = getCookie(this.playerVolumeCookies[player_id]);
		if( cook != undefined && cook != "" )
			return( cook.toString().split( ":" )[1] == "1" );
		else
			return this.defaultMute;
	},
	
	setMute: function( player_id , value ) {
		setCookie( this.playerVolumeCookies[player_id] , this.getVolume( player_id) + ":" + (value ? "1" : "0") );
	},
	
	getVolume: function( player_id) {
		var cook = getCookie(this.playerVolumeCookies[player_id]);
		if( cook != undefined && cook != "" )
			return( cook.toString().split( ":" )[0] );
		else
			return this.defaultVolume;
	},
	
	setVolume: function( player_id , value ) {
		setCookie( this.playerVolumeCookies[player_id] , value.toString() + ":" + (this.getMute( player_id) ? "1" : "0")  );
	},
	
	write: function( file , div_id , width , height , options ) {
		var opts = {};
		// SETUP OPTIONS
		Object.extend( opts , Mixamo.Video.defaultOptions );
		opts["id"] = "player" + this.playerCount.toString();
		this.playerCount += 1;
		
		Mixamo.Video.players[ opts['id'] ] = new Mixamo.VideoPlayer(opts['id']);
		var currPlayer = Mixamo.Video.players[ opts['id'] ];
		
		if( options != undefined )
		{
			if( options["onPlaylistItem"]) {
				currPlayer.onPlaylistItem = options["onPlaylistItem"];
				delete options["onPlaylistItem"];
			}
			
			if( options["onReady"]) {
				currPlayer.onReady = options["onReady"];
				delete options["onReady"];
			}
		
			Object.extend( opts , options );
		}
		
		var cookie_vol = null;
		if( opts["special_cookie"] != undefined && opts["special_cookie"] != "" ) {
			this.playerVolumeCookies[opts["id"]] = opts["special_cookie"];
		} else {
			this.playerVolumeCookies[opts["id"]] = "ltvol";
		}
		
		var vol = this.defaultVolume;
		var mute = this.defaultMute;
		// DETERMINE VOLUME AND MUTE
		if ( !this.volumeIsUserControlled(opts['id'])) {
			if (opts["volume"] != undefined) {
				vol = opts["volume"];
			}
			
			if (opts["mute"] != undefined) {
				mute = opts["mute"];
			}
		} else {
			vol = this.getVolume( opts["id"])
			mute = this.getMute( opts["id"] ).toString();
		}
		
		opts["volume"] = vol;
		opts["mute"] = mute;
		Mixamo.console.info( "Volume set to: " + vol + " : " + mute)
		var s1 = new SWFObject('/mediaplayer-v5/player-licensed.swf',opts["id"], width.toString() , height.toString() , '9');
	    s1.addParam('allowfullscreen','true');
		opts[ 'logo.file' ] = 'http://www.mixamo.com/images/logo.png';
		opts['logo.link'] = 'http://www.mixamo.com';
		opts['logo.hide'] = "true";
		//opts['skin'] = "/mediaplayer-v5/mixamoskin.zip"
		//opts['icons'] = "false";
		s1.addParam( 'playlist' , 'none');
	    s1.addParam('allowscriptaccess','always');
	    s1.addParam('wmode', 'transparent' );
		opts['repeat']  ='list';
		if( opts["playlistfile"] != undefined ) {
			s1.addParam('flashvars', toQueryString(opts) );
		} else {
			s1.addParam('flashvars','file=' + file +  "&" + toQueryString(opts) );
		}
	    s1.write( div_id );
	},
	
	volumeChanged: function( obj ) {
		Mixamo.console.info( "volume changed: " + obj['id'] + " : " + obj.percentage.toString() );
		Mixamo.Video.setVolume( obj['id'] , obj.percentage.toString());
	},
	
	muteChanged: function( obj ) {
		Mixamo.console.info( "mute changed: " + obj['id'] + " : " + obj.state );
		Mixamo.Video.setMute( obj['id'] , (obj.state == true ) );
	},
	
	onPlaylistItem: function(obj) {
		Mixamo.console.info( "onPlaylistItem:" + obj['id'] + " : " + obj.index );		
		if( Mixamo.Video.players[obj['id']].onPlaylistItem != undefined )
			Mixamo.Video.players[obj['id']].onPlaylistItem( obj );
	},
	
	playlistItem: function( player_id , i)
	{
		var player = document.getElementById( player_id );
		player.sendEvent( "ITEM" , i );
	},
	
	onReady: function(obj) {
		var player = document.getElementById(obj['id']);
		var playerObj = Mixamo.Video.players[obj['id']];
		player.addControllerListener("VOLUME","Mixamo.Video.volumeChanged");
		player.addControllerListener("MUTE","Mixamo.Video.muteChanged");
		player.addControllerListener( "ITEM" , "Mixamo.Video.onPlaylistItem");
		
		
		if (playerObj.onReady != undefined) {
			playerObj.onReady( obj );
			delete playerObj.onReady;
		}
		
	}
}



function playerReadyCallbackio(obj) {
	Mixamo.console.info("player ready: " + obj['id']);
	Mixamo.Video.onReady(obj);


};



Mixamo.Background = {
	removeClasses: function() {
		$("body").removeClass( "night evening day" );
	},
	switchToNight: function() {
		this.removeClasses();
		$("body").addClass( "night" );
		setCookie( "bgc" , "night" , 365);
	},
	
	switchToDay: function() {
		this.removeClasses();
		$("body").addClass( "day" );
		setCookie( "bgc" , "day" , 365);
	},
	
	switchToEvening: function() {
		this.removeClasses();
		$("body").addClass( "evening" );
		setCookie( "bgc" , "evening" , 365);
	}
}

Mixamo.FlashVer = {
	requiredMajorVersion: 9,
	// Minor version of Flash required
	requiredMinorVersion: 0,
	// Minor version of Flash required
	requiredRevision: 124
}


Mixamo.Menubar = {
	timeout: 1000,
	closetimer : 0,
	menuitem: 0,
    
	/*capture_key_press: function(e) {
      var keyUp = 38
	  var keyDown = 40;
	  var keyReturn = 13;
	  var key=e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
      if ( Mixamo.Menubar.menuitem && ( key == keyUp || key == keyDown || key == keyReturn) ) {
	  	  
		  Mixamo.console.info(key);
		  e.preventDefault();
		  $(".option" , Mixamo.Menubar.menuitem
		  
          return false;
      }
      return true;
	},*/
	
	open: function( ele , container )
	{
		$("body").one("click", function(){
            Mixamo.Menubar.close();
        });
		
		Mixamo.Menubar.canceltimer();
		Mixamo.Menubar.close();
		
		Mixamo.Menubar.menuitem = $(ele).css( "visibility" , "visible");
		$(container).addClass("mixamo_menubar_selected");
        if( Mixamo.Unity )
		  Mixamo.Unity.Hide( "menubar" );
		 
		 
		// Capture key presses
		

		//$(document).bind('keypress' , Mixamo.Menubar.capture_key_press);


		return false;
	},
	
	close: function( )
	{  
		if (Mixamo.Menubar.menuitem) {
			Mixamo.Menubar.menuitem.css( "visibility" , "hidden");
			$(".mixamo_menubar_selected").removeClass( "mixamo_menubar_selected" );
		}
        if( Mixamo.Unity )
          Mixamo.Unity.Show( "menubar" );
	   
	   //$(document).unbind('keypress' , Mixamo.Menubar.capture_key_press);
	},
	
	timed_close: function()
	{  
		Mixamo.Menubar.closetimer = window.setTimeout(Mixamo.Menubar.close, Mixamo.Menubar.timeout);
	},
	
	canceltimer: function()
	{  
		if(Mixamo.Menubar.closetimer )
	   	{  
			window.clearTimeout(Mixamo.Menubar.closetimer);
	      	Mixamo.Menubar.closetimer = null;
		}
	},
	
	/* 
	 * Example Menu Structure
	 * <div id="something">
	 *     <div class="mixamo_menubar_menu" />
	 *     <div class="mixamo_menubar_selector" />
	 * </div>
	 */
	load: function( menu_bar_containers ) {
		$(menu_bar_containers).each( function() {
			var container = $(this);
			
			$(container).mouseleave( function(){
	            Mixamo.Menubar.timed_close();
	        });
	        
	        $('.mixamo_menubar_menu' , container).mouseenter( function() {
	            Mixamo.Menubar.canceltimer();
	        });
	        
	        $(".mixamo_menubar_selector" , container).click( function(event) {
	            if (event.pageX == 0 && event.pageY == 0) {
	                return true;
	            } else {
	                var this_ele = $(this);
	                var ele = $('.mixamo_menubar_menu', container);
	                
	                Mixamo.Menubar.open(ele , container);
	                return false;
	            }
	        });
		});
	}
	
};


/**
 * Simple Slide Panel Jquery plugin
 */
(function($) {
	$.fn.mixamo_slide_panel = function(options) {
		if (options.sections.length > 0) {
			var self = this;
			
			var headerBaseName = "slidePanelSidebar";
			var numberOfEntries = Math.min(options.sections.length, 5);
			this.addClass('slidePanel').append($('<div class="slidePanelSidebar"></div><div class="slidePanelContent"></div>'));
			
			var currentPanelId = 0;
			var selectPanelFunctions = [null, null, null, null, null];
			for (var i = 0; i < numberOfEntries; i++) {
			
				var ele = $('<div class="slidePanelSidebar' + i + ' slidePanelSidebarPart"><p>' + options.sections[i].header + '</p></div>');
				$(".slidePanelSidebar", self).append(ele);
				
				(function(){
					var contentTag = $(options.sections[i].content);
					var panelId = i;
					selectPanelFunctions[i] = function(){
						Mixamo.console.info( self );
						$(".slidePanelSidebar", self).removeClass("slidePanelSidebar" + currentPanelId + "-active").addClass("slidePanelSidebar" + panelId + "-active");
						currentPanelId = panelId;
						$(".slidePanelContent", self).html(contentTag.html());
					};
					ele.click(selectPanelFunctions[i]);
				})();
			}
			
			selectPanelFunctions[currentPanelId].call();
			
		} else {
			
			Mixamo.console.error( "There must be more than one panel of slides.")
		}
		
	};
})(jQuery);


Mixamo.MouseWheel = {
	
	disable: function() {
    /* Gecko */
    this.addHandler(window, 'DOMMouseScroll', this.wheel);
    /* Opera */
    this.addHandler(window, 'mousewheel', this.wheel);
    /* IE */
    this.addHandler(document, 'mousewheel', this.wheel);
},

enable: function () {
    /* Gecko */
    this.removeHandler(window, 'DOMMouseScroll', this.wheel);
    /* Opera */
    this.removeHandler(window, 'mousewheel', this.wheel);
    /* IE */
    this.removeHandler(document, 'mousewheel', this.wheel);
},

//function for add envent handler
addHandler: function (object, event, handler, useCapture) {
    if (object.addEventListener) {
        object.addEventListener(event, handler, useCapture ? useCapture : false);
    } else if (object.attachEvent) {
        object.attachEvent('on' + event, handler);
    } else Mixamo.console.info("Add handler is not supported");
},

//function for remove envent handler
removeHandler: function (object, event, handler) {
    if (object.removeEventListener) {
        object.removeEventListener(event, handler, false);
    } else if (object.detachEvent) {
        object.detachEvent('on' + event, handler);
    } else Mixamo.console.info("Remove handler is not supported");
},

	// Wheel event handler
	wheel: function (event) {
	    var delta; // Scroll direction
	    // -1 - scroll down
	    // 1  - scroll up
	    event = event || window.event;
	    // Opera & IE works with property wheelDelta
	    if (event.wheelDelta) {
	        delta = event.wheelDelta / 120;
	        // In Опере value of wheelDelta the same but with opposite sign
	        if (window.opera) delta = -delta;
	        // Gecko uses property detail
	    } else if (event.detail) {
	        delta = -event.detail / 3;
	    }
	    // Disables processing events
	    if (event.preventDefault) event.preventDefault();
	    event.returnValue = false;
	    return delta;
	} 
};

function mixamo_disable_mouse_wheel() {
	Mixamo.MouseWheel.disable();
};

function mixamo_enable_mouse_wheel() {
	Mixamo.MouseWheel.enable();
};

/**
 * Rotate panel Jquery
 * @param {Object} panels
 * @param {Object} opts - { interval: time before next panel, transition: ui type transition (fade vs slide) }
 */
(function($) {
	
	function rotatePanelsFunc( self , direction ) {
		if( direction == undefined )
			direction = "next";
			
		self = $(self);
		
		var timeoutIndex = self.data("timeoutIndex");
		if( timeoutIndex >= 0)
			clearTimeout( timeoutIndex );
		
		var options = self.data("options");
		var currentPanelIndex = self.data("currentPanelIndex");
		
		var allPanels = self.children();
		var currPanel,nextPanel;
		currPanel = allPanels[currentPanelIndex % allPanels.length];
		if( direction == "next" )
			currentPanelIndex = (currentPanelIndex == (allPanels.length-1) ? 0 : currentPanelIndex + 1 );
		else
			currentPanelIndex = (currentPanelIndex == 0 ? (allPanels.length-1) : currentPanelIndex - 1 );
		
		nextPanel = allPanels[currentPanelIndex];

		if( options.transition == "slide-horizontal") {
			var w = self.width();
			$(nextPanel).css( {left: (direction == "next" ? w : -w) , opacity: 1.0});
			$( [currPanel, nextPanel] ).animate( {left: ( direction == "next" ? "-=" : "+=" ) + w} , {duration: options.transition_delay, queue: false} );
			
		} else if( options.transition == "slide-vertical") {
			var h = self.height();
			$(nextPanel).css( {top: (direction == "next" ? -h : h) , opacity: 1.0});
			$([currPanel,nextPanel]).animate( {top: ( direction == "next" ? "+=" : "-=" ) + h} , {duration: options.transition_delay, queue: false} );
		} else {
			$(currPanel).removeClass("active").animate( {opacity: 0.0} , {duration: options.transition_delay, queue: false, complete: function() {
				$(this).hide();
			}} );
			$(nextPanel).show().addClass("active").animate( {opacity: 1.0} , {duration: options.transition_delay, queue: false} );
		}
		
		self.data("currentPanelIndex" , currentPanelIndex  );
		
		var timeoutIndex = setTimeout(function(){
			rotatePanelsFunc(self);
		}, options.interval);
		
		self.data("timeoutIndex" , timeoutIndex);
	}

	$.fn.extend( {
		mixamo_rotate_panel_next: function() {
			rotatePanelsFunc(this , "next");
		},
		
		mixamo_rotate_panel_prev: function() {
			rotatePanelsFunc(this , "prev");
		},
		
		mixamo_rotate_panel_pause: function() {
			var timeoutIndex = this.data("timeoutIndex");
			clearTimeout( timeoutIndex );
			this.data("timeoutIndex",-1);
		},
		
		mixamo_rotate_panel_play: function() {
			rotatePanelsFunc(this);
		},
		
		mixamo_rotate_panel: function( opts){
			var self = $(this);
			
			self.data("currentPanelIndex", 0);
			
			var options = $.extend({
				interval: 5000,
				transition: "fade",
				transition_delay: 500
			}, opts ||
			{});
			
			if (options.interval <= options.transition_delay) {
				options.interval = options.transition_delay + 1;
			}
			self.data("options", options);
			
			
			var allPanels = self.children();
			
			if (allPanels.length <= 0) {
				Mixamo.console.error("There aren't enough panels to rotate thru!");
			}
			else {
			
				self.css({
					overflow: "hidden"
				});
				allPanels.css({
					position: "absolute",
					top: 0,
					left: 0,
					opacity: 0.0,
					width: self.width(),
					height: self.height()
				}).hide();
				
				
				$(allPanels[0]).css({
					opacity: 1.0
				}).show().addClass("active");
				
				if (allPanels.length > 1) {
					var to = setTimeout(function(){
						rotatePanelsFunc(self);
					}, options.interval);
					self.data("timeoutIndex" , to);
				}
			}
		}
	} );

})(jQuery);


Mixamo.MotionPurchaser = {
	
	last_start_user_clip_id: null ,
	
	start: function( user_clip_id ) {	
	   
	   if( $("#motionPurchaserDialog").length == 0 ) {
            $('<div id="motionPurchaserDialog" title="Download/Purchase Motion"><div class="miniLoadingContainer" style="display:none;"><img align="absmiddle" src="/images/ajax-loader-small.gif" /></div><div class="loadingContainer mpPanel">Loading ...</div><div id="motionPurchaserOptionsStep" class="mpPanel" style="display:none;"></div><div id="motionPurchaserReviewStep" class="mpPanel" style="display:none;"></div></div>').dialog({ 
                modal: true , 
				dialogClass: "purchaseMotionDialog",
                height: 'auto' ,
				width: 620,
                resizable: false,
                position: [ "center" , 100],
                autoOpen: false,
				close: function() {
					if( Mixamo.Unity )
                        Mixamo.Unity.Show( "purchaser" );
				}
            });
       }
	   
	   var ele = $("#motionPurchaserDialog");
	   $(".mpPanel" ,ele).hide();
	   $(".loadingContainer" ,ele).show();
	   this.show_mini_loading();
	          
	   if( Mixamo.Unity )
            Mixamo.Unity.Hide( "purchaser" );
	   ele.dialog('open');
	   $.ajax( {
	   	type: "GET",
	   	url: "/carts/purchase_user_clip/" + user_clip_id,
	   	dataType: "script",
		error: function() { Mixamo.error(); }
		
	   });
	   last_start_user_clip_id = user_clip_id;
	},
	
	restart: function() {
		if( !last_start_user_clip_id ) {
			Mixamo.error();
		} else {
			this.start( last_start_user_clip_id );
		}
	},
	
	back_to_options: function() {
		$("#motionPurchaserDialog .mpPanel").hide();
		$("#motionPurchaserOptionsStep").show();
		Mixamo.enableButton( $("#motionPurchaserDialog :submit") );
	},
	
	
	load_options: function( json ) {
		Mixamo.GoogleAnalytics.trackPageview('/purchase_options');
		
		var self = this;
		Mixamo.ApplyPromo.init( function() {
			alert( "Your promotion has been applied!" );
			Mixamo.MotionPurchaser.restart();
		});
		
		$('#payOptionsTabs').tabs( { collapsible: false } );

        //
        // disable the mixamo credits tab if applicable
        //
        
        if(json.disable_mixamocredits) {
            $( '#payOptionsTabs' ).tabs( "option", "selected", 1 );
            $( '#payOptionsTabs' ).tabs( "option", "disabled", [0] );

            $( '#payOptionsTabs ul:first li:first' ).tooltip({
                delay: 0,
                showURL: true,
                extraClass: "motionPurchasertooltip",
                bodyHandler: function() {
                    return json.disable_mixamocredits;
                }
            });
        } else {
            $( '#payOptionsTabs' ).tabs( "option", "disabled", [] );
            $( '#payOptionsTabs' ).tabs( "option", "selected", 0 );

            $( '#payOptionsTabs ul:first li:first' ).tooltip();
        }

		$("#payOptionsTabs .eo_tooltip_hover").tooltip({
            delay: 0,
            showURL: true,
            left: -50,
			extraClass: "motionPurchasertooltip",
            bodyHandler: function() {                         
                return $("div.eo_tooltip_body" , this).text();
            }
        });
		
		var pricingArrayCredits = []; var pricingArrayCC = [];
		
		pricingArrayCredits.push( { is_selected : function() { return true; } , price: json.user_clip.price_credits } );
		pricingArrayCC.push( { is_selected : function() { return true; } , price: json.user_clip.price } );

        if(json.evolver_purchase != null) {
            pricingArrayCredits.push( { is_selected : function() { return true; } , price: json.evolver_purchase.price_credits } );
            pricingArrayCC.push(      { is_selected : function() { return true; } , price: json.evolver_purchase.price } );
        }

		$(json.variation_offers).each( function() {
			var vo = this;
			pricingArrayCredits.push( { 
			 is_selected: function() {
				    return( $("#credit_variation_offers_id_" + vo.id ).is(":checked") );
				 } , 
		     price: vo.price_credits });
			pricingArrayCC.push( { 
             is_selected: function() {
                    return( $("#cc_variation_offers_id_" + vo.id ).is(":checked") );
                 } , 
             price: vo.price });
		});
		
		if( json.character_group_purchase != null )
		{
			pricingArrayCredits.push( {
				is_selected: function() {
					var e = $("#credit_purchase_character");
                    if( e.attr("type") == "hidden" )
                       return true;
                    else
                       return( e.is(":checked") );
				},
				price: json.character_group_purchase.price_credits
			});
			
			pricingArrayCC.push( {
                is_selected: function() {
                    var e = $("#cc_purchase_character");
                    if( e.attr("type") == "hidden" )
                       return true;
                    else
                       return( e.is(":checked") );
                },
                price: json.character_group_purchase.price
            });
		}

		var priceCheckerCredits = new Mixamo.PriceChecker(  pricingArrayCredits , function( total  ) {
			if( total <= json.user.credit_freebies ) {
		        $("#credit_calc_total").text( (json.user.credit_freebies - total).toString() );
                self.hide_errors();
				Mixamo.enableButton('#purchaseBtnCredits');
			} else {
				$("#credit_calc_total").text( "---" );
                Mixamo.disableButton('#purchaseBtnCredits');
				self.show_errors( ["You do not have enough credits to purchase this order!"] );
			}
			return true;
		} );
		
		var priceCheckerCC = new Mixamo.PriceChecker( pricingArrayCC , function( total ) {
			$("#cc_calc_total").text( total.toFixed(2) );
		});
		
		$("#payWithCreditsOption input.purchase_item").click( function() {
			priceCheckerCredits.update_amount();
			var ele = $(this);
			var p_ele = ele.parents("tr.extra_option_tr");
			if (ele.is(":checked")) {
			     p_ele.addClass( "extra_option_tr_selected");
			} else {
				p_ele.removeClass( "extra_option_tr_selected");
			}
		});
		
		
		$("#payWithCCOption input.purchase_item").click( function() {
            priceCheckerCC.update_amount();
            var ele = $(this);
            var p_ele = ele.parents("tr.extra_option_tr");
            if (ele.is(":checked")) {
                p_ele.addClass( "extra_option_tr_selected");
            } else {
                p_ele.removeClass( "extra_option_tr_selected");
            }
        });
		
		priceCheckerCredits.update_amount();
		priceCheckerCC.update_amount();
		
		$("#motionPurchaserDialog .mpPanel").hide();
        $("#motionPurchaserOptionsStep").show();
		
		this.hide_mini_loading();
	},
	
	next_step: function( submit_form ) {
		this.show_mini_loading();
		return Mixamo.disableButton( $("input:submit", $(submit_form)) );	
	},
	
	load_review: function() {
		Mixamo.GoogleAnalytics.trackPageview('/purchase_review_cc');
		
		$("#btnBackToOptions").click( function() {
			Mixamo.MotionPurchaser.back_to_options();
			return false;
		});
		
		$("#motionPurchaserDialog .mpPanel").hide();
        $("#motionPurchaserReviewStep").show();
		
		this.hide_mini_loading();
	},
	
	succeed: function( alert_msg ) {
		Mixamo.MotionPurchaser.close();
		Mixamo.BottomDownloader.open({reload: true , alert: alert_msg});
	},
	
	close: function() {
		$("#motionPurchaserDialog").dialog('close');
	},
	
	show_errors: function( errors ) {
		this.hide_errors();
		var active_ele = $(".paymentErrorRegion:visible");
		Mixamo.console.info( errors );
		$.each( errors, function( index , val) {
		  var err_ele = $("<div></div>");
		  err_ele.text( val );
		  active_ele.append(err_ele);
		});
   	},
	
	hide_errors: function( ) {
		this.hide_mini_loading();
		var ele = $(".paymentErrorRegion");
        ele.html("");
	},
	
	show_mini_loading: function() {
		$("#motionPurchaserDialog .miniLoadingContainer").show();
	},
	
	hide_mini_loading: function() {
		$("#motionPurchaserDialog .miniLoadingContainer").hide();
	}
	
};


Mixamo.PriceChecker = function(  pricingArray ,  onUpdate) {
    this.pricingArray = pricingArray;
    this.onUpdate = onUpdate;
};

Mixamo.PriceChecker.prototype = {
    update_amount: function() {
        var totalAmount = 0;
        $(this.pricingArray).each( function(){
            if( this.is_selected() )
               totalAmount += this.price;
        });
        
        return( this.onUpdate( totalAmount  ));
    }
};


Mixamo.ApplyPromo = {
	
	init: function( success_callback ) {
	   $(".addPromotionCodeDiv .promoSubmitBtn").click( function() {
	   	  var parentEle = $(this).parent();
		  $.ajax( {
		  	type: "POST",
			dataType: "json",
		  	url: "/carts/apply_promo",
			data: { code: $(".promo_input_code",parentEle).val() },
			beforeSend: function() {
				$('.promoCodeLoading',parentEle).show();
			},
			complete: function() {
				$('.promoCodeLoading' , parentEle).hide();
			},
			success: function(data) {
				if (!data.success) {
					$('.promoCodeError' , parentEle).text(data.error_message)
				}
				else {
					if (success_callback == undefined) {
						alert('Promo Applied!');
						Mixamo.refresh_page();
					}
					else {
						success_callback.call();
					}
				}
				    
			},
			error: function() {
				Mixamo.error();
			}
		  });
		
		  return false;
	   } );	
	}
};


Mixamo.Tooltips = {
	options: {delay: 0,
            showURL: true,
            left: -50
            },
	load: function() {
		$(".mixamo_tooltip").tooltip(this.options);
	}
	
};


Mixamo.CharacterNotifier = {
	STARTING_TIMER_MS: 45000,
	
	query_notifications: function () {
	   Mixamo.CharacterNotifier.nextQueryTO = setTimeout( Mixamo.CharacterNotifier.query_notifications_helper , this.STARTING_TIMER_MS );
	},
	
	query_notifications_helper: function() {
		var nextTimeoutMs = Mixamo.CharacterNotifier.STARTING_TIMER_MS;
		
		if ($("#characterNotificationContainer").length == 0) {
            $.get("/characters/get_not_notified_characters", {}, function(data){
                if (data.not_notified_character_ids.length > 0) {
					Mixamo.CharacterNotifier.notify_user(data.not_notified_character_ids);
					if( Mixamo.CharacterNotifier.isOnMyStuffPage() ) {
                        $('#skeletons').trigger("reloadGrid");
                    }
                }
            }, "json");
        }
		
		Mixamo.CharacterNotifier.nextQueryTO = setTimeout( Mixamo.CharacterNotifier.query_notifications_helper , nextTimeoutMs );
	},
	
	notify_user: function(arr) {
		var self = this;
		if (arr.length > 0) {
			var ele = $("#characterNotificationContainer");
			var str;
			var msg;
			if (arr.length == 1) {
				msg = 'You have (' + arr.length + ') pro character ready for use.'
			} else {
				msg = 'You have (' + arr.length + ') pro characters ready for use.'
			}
			str = '<div class="cn_menubar"><div class="cn_menutext">' + msg + '</div>';
	        str += '<em class="mixamo_menubar_selector"></em>'
	        str += '<div class="mixamo_menubar_menu" style="visibility: hidden"><ul>'
	        
			motionsUrl = self.dismiss_notifications_url( arr , "/motions?character_id=" + arr[0] );
            mystuffUrl = self.dismiss_notifications_url( arr , "/mystuff" );
			if( Mixamo.viewCharacterSpecialMotionId > 0 )
			 viewUrl = self.dismiss_notifications_url( arr , "/editor/test_character/" + arr[0]);
			
			if( arr.length == 1 )
			{
				if (Mixamo.Editor) {
				 str += '<li class="first cn_preview"><a href="#nogo">Preview character on current motion</a></li>';
				 str += '<li class="middle cn_select"><a href="' + motionsUrl + '">Select a motion for your character</a></li>';
				} else {
				 str += '<li class="first cn_select"><a href="' + motionsUrl + '">Select a motion for your character</a></li>';
				}
				
				if( viewUrl ) {
		          str += '<li class="middle cn_view"><a href="' + viewUrl + '">View your character</a></li>';
				}
				if( !self.isOnMyStuffPage() ) {
					str += '<li class="middle cn_mystuff"><a href="' + mystuffUrl + '">Go to My Stuff</a></li>';
				}
				
				str += '<li class="middle cn_dismiss"><a href="#nogo">Dismiss</a></li>'
                str += '<li class="last"></li>'
				
	        } else {
				if (!self.isOnMyStuffPage()) {
					str += '<li class="first cn_mystuff"><a href="' + mystuffUrl + '">Go to My Stuff</a></li>';
					str += '<li class="middle cn_dismiss"><a href="#nogo">Dismiss</a></li>'
                    str += '<li class="last"></li>'
				} else {
					str += '<li class="first cn_dismiss"><a href="#nogo">Dismiss</a></li>'
                    str += '<li class="last"></li>'
				}
			}
			
			
			str += '</ul></div></div>'
			
			if (ele.length > 0) 
				ele.html(str);
			else 
				add_flash_notice('<div id="characterNotificationContainer">' + str + '</div>');
				
			Mixamo.Menubar.load( $("#characterNotificationContainer") );
			
			if (Mixamo.Editor) {
				$("#characterNotificationContainer .cn_preview a").click(function(){				    
					Mixamo.Menubar.close();
					Mixamo.Editor.RetargetingWidget.reload_characters_tab( "custom" , function() { 
					   $("#attachedCharacterSelect_" + arr[0]).click();
					   
					   //if( !Mixamo.Editor.RetargetingWidget.change_character_by_id( arr[0] ) )
					   //    alert( "Character could not be loaded! Please refresh the page and try again.");
					} );
					
					Mixamo.CharacterNotifier.dismiss_notifications( arr );
				    return false;
				});
			}
			
			$("#characterNotificationContainer .cn_dismiss a").click( function() {
                Mixamo.Menubar.close();
                Mixamo.CharacterNotifier.dismiss_notifications( arr);
                return false;
            });
			
		}
		
		return false;
		
	}, 
	
	isOnMyStuffPage: function() {
		return( document.location.href.indexOf("/mystuff") >= 0 );
	},
	dismiss_notifications: function( arr )
	{
		destroy_flash_notice();
		$.post( "/characters/dismiss_notifications" , {
			"ids": arr.join(",") , "format": "json" }, function(data) {} , "json" );
		
	},
	
	dismiss_notifications_url: function( arr , redir )
	{
		return( "/characters/dismiss_notifications?ids=" + escape( arr.join(",") ) + "&redir=" + escape( redir ) );
	}
};




