/*
 * transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate()
 *
 * limitations:
 * - requires jQuery 1.4.3+
 * - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**.
 * - transformOrigin is not accessible
 *
 * latest version and complete README available on Github:
 * https://github.com/louisremi/jquery.transform.js
 *
 * Copyright 2011 @louis_remi
 * Licensed under the MIT license.
 *
 * This saved you an hour of work?
 * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
 *
 */
(function( $ ) {

/*
 * Feature tests and global variables
 */
var div = document.createElement('div'),
	divStyle = div.style,
	propertyName = 'transform',
	suffix = 'Transform',
	testProperties = [
		'O' + suffix,
		'ms' + suffix,
		'Webkit' + suffix,
		'Moz' + suffix,
		// prefix-less property
		propertyName
	],
	i = testProperties.length,
	supportProperty,
	supportMatrixFilter,
	propertyHook,
	propertyGet,
	rMatrix = /Matrix([^)]*)/;

// test different vendor prefixes of this property
while ( i-- ) {
	if ( testProperties[i] in divStyle ) {
		$.support[propertyName] = supportProperty = testProperties[i];
		continue;
	}
}
// IE678 alternative
if ( !supportProperty ) {
	$.support.matrixFilter = supportMatrixFilter = divStyle.filter === '';
}
// prevent IE memory leak
div = divStyle = null;

// px isn't the default unit of this property
$.cssNumber[propertyName] = true;

/*
 * fn.css() hooks
 */
if ( supportProperty && supportProperty != propertyName ) {
	// Modern browsers can use jQuery.cssProps as a basic hook
	$.cssProps[propertyName] = supportProperty;
	
	// Firefox needs a complete hook because it stuffs matrix with 'px'
	if ( supportProperty == 'Moz' + suffix ) {
		propertyHook = {
			get: function( elem, computed ) {
				return (computed ?
					// remove 'px' from the computed matrix
					$.css( elem, supportProperty ).split('px').join(''):
					elem.style[supportProperty]
				)
			},
			set: function( elem, value ) {
				// remove 'px' from matrices
				elem.style[supportProperty] = /matrix[^)p]*\)/.test(value) ?
					value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, 'matrix$1$2px,$3px'):
					value;
			}
		}
	/* Fix two jQuery bugs still present in 1.5.1
	 * - rupper is incompatible with IE9, see http://jqbug.com/8346
	 * - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402
	 */
	} else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) {
		propertyHook = {
			get: function( elem, computed ) {
				return (computed ?
					$.css( elem, supportProperty.replace(/^ms/, 'Ms') ):
					elem.style[supportProperty]
				)
			}
		}
	}
	/* TODO: leverage hardware acceleration of 3d transform in Webkit only
	else if ( supportProperty == 'Webkit' + suffix && support3dTransform ) {
		propertyHook = {
			set: function( elem, value ) {
				elem.style[supportProperty] = 
					value.replace();
			}
		}
	}*/
	
} else if ( supportMatrixFilter ) {
	propertyHook = {
		get: function( elem, computed ) {
			var elemStyle = ( computed && elem.currentStyle ? elem.currentStyle : elem.style ),
				matrix;

			if ( elemStyle && rMatrix.test( elemStyle.filter ) ) {
				matrix = RegExp.$1.split(',');
				matrix = [
					matrix[0].split('=')[1],
					matrix[2].split('=')[1],
					matrix[1].split('=')[1],
					matrix[3].split('=')[1]
				];
			} else {
				matrix = [1,0,0,1];
			}
			matrix[4] = elemStyle ? elemStyle.left : 0;
			matrix[5] = elemStyle ? elemStyle.top : 0;
			return "matrix(" + matrix + ")";
		},
		set: function( elem, value, animate ) {
			var elemStyle = elem.style,
				currentStyle,
				Matrix,
				filter;

			if ( !animate ) {
				elemStyle.zoom = 1;
			}

			value = matrix(value);

			// rotate, scale and skew
			if ( !animate || animate.M ) {
				Matrix = [
					"Matrix("+
						"M11="+value[0],
						"M12="+value[2],
						"M21="+value[1],
						"M22="+value[3],
						"SizingMethod='auto expand'"
				].join();
				filter = ( currentStyle = elem.currentStyle ) && currentStyle.filter || elemStyle.filter || "";

				elemStyle.filter = rMatrix.test(filter) ?
					filter.replace(rMatrix, Matrix) :
					filter + " progid:DXImageTransform.Microsoft." + Matrix + ")";

				// center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie
				if ( (centerOrigin = $.transform.centerOrigin) ) {
					elemStyle[centerOrigin == 'margin' ? 'marginLeft' : 'left'] = -(elem.offsetWidth/2) + (elem.clientWidth/2) + 'px';
					elemStyle[centerOrigin == 'margin' ? 'marginTop' : 'top'] = -(elem.offsetHeight/2) + (elem.clientHeight/2) + 'px';
				}
			}

			// translate
			if ( !animate || animate.T ) {
				// We assume that the elements are absolute positionned inside a relative positionned wrapper
				elemStyle.left = value[4] + 'px';
				elemStyle.top = value[5] + 'px';
			}
		}
	}
}
// populate jQuery.cssHooks with the appropriate hook if necessary
if ( propertyHook ) {
	$.cssHooks[propertyName] = propertyHook;
}
// we need a unique setter for the animation logic
propertyGet = propertyHook && propertyHook.get || $.css;

/*
 * fn.animate() hooks
 */
$.fx.step.transform = function( fx ) {
	var elem = fx.elem,
		start = fx.start,
		end = fx.end,
		split,
		pos = fx.pos,
		transform,
		translate,
		rotate,
		scale,
		skew,
		T = false,
		M = false,
		prop;
	translate = rotate = scale = skew = '';

	// fx.end and fx.start need to be converted to their translate/rotate/scale/skew components
	// so that we can interpolate them
	if ( !start || typeof start === "string" ) {
		// the following block can be commented out with jQuery 1.5.1+, see #7912
		if (!start) {
			start = propertyGet( elem, supportProperty );
		}

		// force layout only once per animation
		if ( supportMatrixFilter ) {
			elem.style.zoom = 1;
		}

		// if the start computed matrix is in end, we are doing a relative animation
		split = end.split(start);
		if ( split.length == 2 ) {
			// remove the start computed matrix to make animations more accurate
			end = split.join('');
			fx.origin = start;
			start = 'none';
		}

		// start is either 'none' or a matrix(...) that has to be parsed
		fx.start = start = start == 'none'?
			{
				translate: [0,0],
				rotate: 0,
				scale: [1,1],
				skew: [0,0]
			}:
			unmatrix( toArray(start) );

		// fx.end has to be parsed and decomposed
		fx.end = end = ~end.indexOf('matrix')?
			// bullet-proof parser
			unmatrix(matrix(end)):
			// faster and more precise parser
			components(end);

		// get rid of properties that do not change
		for ( prop in start) {
			if ( prop == 'rotate' ?
				start[prop] == end[prop]:
				start[prop][0] == end[prop][0] && start[prop][1] == end[prop][1]
			) {
				delete start[prop];
			}
		}
	}

	/*
	 * We want a fast interpolation algorithm.
	 * This implies avoiding function calls and sacrifying DRY principle:
	 * - avoid $.each(function(){})
	 * - round values using bitewise hacks, see http://jsperf.com/math-round-vs-hack/3
	 */
	if ( start.translate ) {
		// round translate to the closest pixel
		translate = ' translate('+
			((start.translate[0] + (end.translate[0] - start.translate[0]) * pos + .5) | 0) +'px,'+
			((start.translate[1] + (end.translate[1] - start.translate[1]) * pos + .5) | 0) +'px'+
		')';
		T = true;
	}
	if ( start.rotate != undefined ) {
		rotate = ' rotate('+ (start.rotate + (end.rotate - start.rotate) * pos) +'rad)';
		M = true;
	}
	if ( start.scale ) {
		scale = ' scale('+
			(start.scale[0] + (end.scale[0] - start.scale[0]) * pos) +','+
			(start.scale[1] + (end.scale[1] - start.scale[1]) * pos) +
		')';
		M = true;
	}
	if ( start.skew ) {
		skew = ' skew('+
			(start.skew[0] + (end.skew[0] - start.skew[0]) * pos) +'rad,'+
			(start.skew[1] + (end.skew[1] - start.skew[1]) * pos) +'rad'+
		')';
		M = true;
	}

	// In case of relative animation, restore the origin computed matrix here.
	transform = fx.origin ?
		fx.origin + translate + skew + scale + rotate:
		translate + rotate + scale + skew;

	propertyHook && propertyHook.set ?
		propertyHook.set( elem, transform, {M: M, T: T} ):
		elem.style[supportProperty] = transform;
};

/*
 * Utility functions
 */

// turns a transform string into its 'matrix(A,B,C,D,X,Y)' form (as an array, though)
function matrix( transform ) {
	transform = transform.split(')');
	var
			trim = $.trim
		// last element of the array is an empty string, get rid of it
		, i = transform.length -1
		, split, prop, val
		, A = 1
		, B = 0
		, C = 0
		, D = 1
		, A_, B_, C_, D_
		, tmp1, tmp2
		, X = 0
		, Y = 0
		;
	// Loop through the transform properties, parse and multiply them
	while (i--) {
		split = transform[i].split('(');
		prop = trim(split[0]);
		val = split[1];
		A_ = B_ = C_ = D_ = 0;

		switch (prop) {
			case 'translateX':
				X += parseInt(val, 10);
				continue;

			case 'translateY':
				Y += parseInt(val, 10);
				continue;

			case 'translate':
				val = val.split(',');
				X += parseInt(val[0], 10);
				Y += parseInt(val[1] || 0, 10);
				continue;

			case 'rotate':
				val = toRadian(val);
				A_ = Math.cos(val);
				B_ = Math.sin(val);
				C_ = -Math.sin(val);
				D_ = Math.cos(val);
				break;

			case 'scaleX':
				A_ = val;
				D_ = 1;
				break;

			case 'scaleY':
				A_ = 1;
				D_ = val;
				break;

			case 'scale':
				val = val.split(',');
				A_ = val[0];
				D_ = val.length>1 ? val[1] : val[0];
				break;

			case 'skewX':
				A_ = D_ = 1;
				C_ = Math.tan(toRadian(val));
				break;

			case 'skewY':
				A_ = D_ = 1;
				B_ = Math.tan(toRadian(val));
				break;

			case 'skew':
				A_ = D_ = 1;
				val = val.split(',');
				C_ = Math.tan(toRadian(val[0]));
				B_ = Math.tan(toRadian(val[1] || 0));
				break;

			case 'matrix':
				val = val.split(',');
				A_ = +val[0];
				B_ = +val[1];
				C_ = +val[2];
				D_ = +val[3];
				X += parseInt(val[4], 10);
				Y += parseInt(val[5], 10);
		}
		// Matrix product
		tmp1 = A * A_ + B * C_;
		B    = A * B_ + B * D_;
		tmp2 = C * A_ + D * C_;
		D    = C * B_ + D * D_;
		A = tmp1;
		C = tmp2;
	}
	return [A,B,C,D,X,Y];
}

// turns a matrix into its rotate, scale and skew components
// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp
function unmatrix(matrix) {
	var
			scaleX
		, scaleY
		, skew
		, A = matrix[0]
		, B = matrix[1]
		, C = matrix[2]
		, D = matrix[3]
		;

	// Make sure matrix is not singular
	if ( A * D - B * C ) {
		// step (3)
		scaleX = Math.sqrt( A * A + B * B );
		A /= scaleX;
		B /= scaleX;
		// step (4)
		skew = A * C + B * D;
		C -= A * skew;
		D -= B * skew;
		// step (5)
		scaleY = Math.sqrt( C * C + D * D );
		C /= scaleY;
		D /= scaleY;
		skew /= scaleY;
		// step (6)
		if ( A * D < B * C ) {
			//scaleY = -scaleY;
			//skew = -skew;
			A = -A;
			B = -B;
			skew = -skew;
			scaleX = -scaleX;
		}

	// matrix is singular and cannot be interpolated
	} else {
		rotate = scaleX = scaleY = skew = 0;
	}

	return {
		translate: [+matrix[4], +matrix[5]],
		rotate: Math.atan2(B, A),
		scale: [scaleX, scaleY],
		skew: [skew, 0]
	}
}

// parse tranform components of a transform string not containing 'matrix(...)'
function components( transform ) {
	// split the != transforms
  transform = transform.split(')');

	var translate = [0,0],
    rotate = 0,
    scale = [1,1],
    skew = [0,0],
    i = transform.length -1,
    trim = $.trim,
    split, name, value;

  // add components
  while ( i-- ) {
    split = transform[i].split('(');
    name = trim(split[0]);
    value = split[1];
    
    if (name == 'translateX') {
      translate[0] += parseInt(value, 10);

    } else if (name == 'translateY') {
      translate[1] += parseInt(value, 10);

    } else if (name == 'translate') {
      value = value.split(',');
      translate[0] += parseInt(value[0], 10);
      translate[1] += parseInt(value[1] || 0, 10);

    } else if (name == 'rotate') {
      rotate += toRadian(value);

    } else if (name == 'scaleX') {
      scale[0] *= value;

    } else if (name == 'scaleY') {
      scale[1] *= value;

    } else if (name == 'scale') {
      value = value.split(',');
      scale[0] *= value[0];
      scale[1] *= (value.length>1? value[1] : value[0]);

    } else if (name == 'skewX') {
      skew[0] += toRadian(value);

    } else if (name == 'skewY') {
      skew[1] += toRadian(value);

    } else if (name == 'skew') {
      value = value.split(',');
      skew[0] += toRadian(value[0]);
      skew[1] += toRadian(value[1] || '0');
    }
	}

  return {
    translate: translate,
    rotate: rotate,
    scale: scale,
    skew: skew
  };
}

// converts an angle string in any unit to a radian Float
function toRadian(value) {
	return ~value.indexOf('deg') ?
		parseInt(value,10) * (Math.PI * 2 / 360):
		~value.indexOf('grad') ?
			parseInt(value,10) * (Math.PI/200):
			parseFloat(value);
}

// Converts 'matrix(A,B,C,D,X,Y)' to [A,B,C,D,X,Y]
function toArray(matrix) {
	// Fremove the unit of X and Y for Firefox
	matrix = /\(([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix);
	return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]];
}

$.transform = {
	centerOrigin: 'margin'
};

})( jQuery );;
/*
jQuery grab 
https://github.com/jussi-kalliokoski/jQuery.grab
Ported from Jin.js::gestures   
https://github.com/jussi-kalliokoski/jin.js/
Created by Jussi Kalliokoski
Licensed under MIT License. 

Includes fix for IE
*/


(function($){
	var	extend		= $.extend,
		mousedown	= 'mousedown',
		mousemove	= 'mousemove',
		mouseup		= 'mouseup',
		touchstart	= 'touchstart',
		touchmove	= 'touchmove',
		touchend	= 'touchend',
		touchcancel	= 'touchcancel';

	function unbind(elem, type, func){
		if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin.
			return $(elem).unbind(type, func);
		}
		var fnc, i;
		for (i=0; i<bind._binds.length; i++){
			if (bind._binds[i].elem === elem && bind._binds[i].type === type && bind._binds[i].func === func){
				if (document.addEventListener){
					elem.removeEventListener(type, bind._binds[i].fnc, false);
				} else {
					elem.detachEvent('on'+type, bind._binds[i].fnc);
				}
				bind._binds.splice(i--, 1);
			}
		}
	}

	function bind(elem, type, func, pass){
		if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin.
			return $(elem).bind(type, pass, func);
		}
		var fnc, i;
		if (bind[type]){
			return bind[type].bind(elem, type, func, pass);
		}
		fnc = function(e){
			if (!e){ // Fix some ie bugs...
				e = window.event;
			}
			if (!e.stopPropagation){
				e.stopPropagation = function(){ this.cancelBubble = true; };
			}
			e.data = pass;
			func.call(elem, e);
		};
		if (document.addEventListener){
			elem.addEventListener(type, fnc, false);
		} else {
			elem.attachEvent('on' + type, fnc);
		}
		bind._binds.push({elem: elem, type: type, func: func, fnc: fnc});
	}

	function grab(elem, options)
	{
		var data = {
			move: {x: 0, y: 0},
			offset: {x: 0, y: 0},
			position: {x: 0, y: 0},
			start: {x: 0, y: 0},
			affects: document.documentElement,
			stopPropagation: false,
			preventDefault: true,
			touch: true // Implementation unfinished, and doesn't support multitouch
		};
		extend(data, options);
		data.element = elem;
		bind(elem, mousedown, mouseDown, data);
		if (data.touch){
			bind(elem, touchstart, touchStart, data);
		}
	}
	function ungrab(elem){
		unbind(elem, mousedown, mousedown);
	}
	function mouseDown(e){
		e.data.position.x = e.pageX;
		e.data.position.y = e.pageY;
		e.data.start.x = e.pageX;
		e.data.start.y = e.pageY;
		e.data.event = e;
		if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)){
			return;
		}
		if (e.preventDefault && e.data.preventDefault){
			e.preventDefault();
		}
		if (e.stopPropagation && e.data.stopPropagation){
			e.stopPropagation();
		}
		bind(e.data.affects, mousemove, mouseMove, e.data);
		bind(e.data.affects, mouseup, mouseUp, e.data);
	}
	function mouseMove(e){
		if (e.preventDefault && e.data.preventDefault){
			e.preventDefault();
		}
		if (e.stopPropagation && e.data.preventDefault){
			e.stopPropagation();
		}
		e.data.move.x = e.pageX - e.data.position.x;
		e.data.move.y = e.pageY - e.data.position.y;
		e.data.position.x = e.pageX;
		e.data.position.y = e.pageY;
		e.data.offset.x = e.pageX - e.data.start.x;
		e.data.offset.y = e.pageY - e.data.start.y;
		e.data.event = e;
		if (e.data.onmove){
			e.data.onmove.call(e.data.element, e.data);
		}
	}
	function mouseUp(e){
		if (e.preventDefault && e.data.preventDefault){
			e.preventDefault();
		}
		if (e.stopPropagation && e.data.stopPropagation){
			e.stopPropagation();
		}
		unbind(e.data.affects, mousemove, mouseMove);
		unbind(e.data.affects, mouseup, mouseUp);
		e.data.event = e;
		if (e.data.onfinish){
			e.data.onfinish.call(e.data.element, e.data);
		}
	}
	function touchStart(e){
		e.data.position.x = e.touches[0].pageX;
		e.data.position.y = e.touches[0].pageY;
		e.data.start.x = e.touches[0].pageX;
		e.data.start.y = e.touches[0].pageY;
		e.data.event = e;
		if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)){
			return;
		}
		if (e.preventDefault && e.data.preventDefault){
			e.preventDefault();
		}
		if (e.stopPropagation && e.data.stopPropagation){
			e.stopPropagation();
		}
		bind(e.data.affects, touchmove, touchMove, e.data);
		bind(e.data.affects, touchend, touchEnd, e.data);
	}
	function touchMove(e){
		if (e.preventDefault && e.data.preventDefault){
			e.preventDefault();
		}
		if (e.stopPropagation && e.data.stopPropagation){
			e.stopPropagation();
		}
		e.data.move.x = e.touches[0].pageX - e.data.position.x;
		e.data.move.y = e.touches[0].pageY - e.data.position.y;
		e.data.position.x = e.touches[0].pageX;
		e.data.position.y = e.touches[0].pageY;
		e.data.offset.x = e.touches[0].pageX - e.data.start.x;
		e.data.offset.y = e.touches[0].pageY - e.data.start.y;
		e.data.event = e;
		if (e.data.onmove){
			e.data.onmove.call(e.data.elem, e.data);
		}
	}
	function touchEnd(e){
		if (e.preventDefault && e.data.preventDefault){
			e.preventDefault();
		}
		if (e.stopPropagation && e.data.stopPropagation){
			e.stopPropagation();
		}
		unbind(e.data.affects, touchmove, touchMove);
		unbind(e.data.affects, touchend, touchEnd);
		e.data.event = e;
		if (e.data.onfinish){
			e.data.onfinish.call(e.data.element, e.data);
		}
	}

	bind._binds = [];

	$.fn.grab = function(a, b){
		return this.each(function(){
			return grab(this, a, b);
		});
	};
	$.fn.ungrab = function(a){
		return this.each(function(){
			return ungrab(this, a);
		});
	};
})(jQuery);;
/*
 * jPlayer Plugin for jQuery JavaScript Library
 * http://www.jplayer.org
 *
 * Copyright (c) 2009 - 2011 Happyworm Ltd
 * Dual licensed under the MIT and GPL licenses.
 *  - http://www.opensource.org/licenses/mit-license.php
 *  - http://www.gnu.org/copyleft/gpl.html
 *
 * Author: Mark J Panaghiston
 * Version: 2.0.15
 * Date: 21th June 2011
 */

/* Code verified using http://www.jshint.com/ */
/*jshint asi:false, bitwise:false, boss:false, browser:true, curly:true, debug:false, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:true, noarg:true, noempty:true, nonew:true, nomem:false, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false */
/*global jQuery:false, ActiveXObject:false, alert:false */

(function($, undefined) {

	// Adapted from jquery.ui.widget.js (1.8.7): $.widget.bridge
	$.fn.jPlayer = function( options ) {
		var name = "jPlayer";
		var isMethodCall = typeof options === "string",
			args = Array.prototype.slice.call( arguments, 1 ),
			returnValue = this;

		// allow multiple hashes to be passed on init
		options = !isMethodCall && args.length ?
			$.extend.apply( null, [ true, options ].concat(args) ) :
			options;

		// prevent calls to internal methods
		if ( isMethodCall && options.charAt( 0 ) === "_" ) {
			return returnValue;
		}

		if ( isMethodCall ) {
			this.each(function() {
				var instance = $.data( this, name ),
					methodValue = instance && $.isFunction( instance[options] ) ?
						instance[ options ].apply( instance, args ) :
						instance;
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue;
					return false;
				}
			});
		} else {
			this.each(function() {
				var instance = $.data( this, name );
				if ( instance ) {
					// instance.option( options || {} )._init(); // Orig jquery.ui.widget.js code: Not recommend for jPlayer. ie., Applying new options to an existing instance (via the jPlayer constructor) and performing the _init(). The _init() is what concerns me. It would leave a lot of event handlers acting on jPlayer instance and the interface.
					instance.option( options || {} ); // The new constructor only changes the options. Changing options only has basic support atm.
				} else {
					$.data( this, name, new $.jPlayer( options, this ) );
				}
			});
		}

		return returnValue;
	};

	$.jPlayer = function( options, element ) {
		// allow instantiation without initializing for simple inheritance
		if ( arguments.length ) {
			this.element = $(element);
			this.options = $.extend(true, {},
				this.options,
				options
			);
			var self = this;
			this.element.bind( "remove.jPlayer", function() {
				self.destroy();
			});
			this._init();
		}
	};
	// End of: (Adapted from jquery.ui.widget.js (1.8.7))

	// Emulated HTML5 methods and properties
	$.jPlayer.emulateMethods = "load play pause";
	$.jPlayer.emulateStatus = "src readyState networkState currentTime duration paused ended playbackRate";
	$.jPlayer.emulateOptions = "muted volume";

	// Reserved event names generated by jPlayer that are not part of the HTML5 Media element spec
	$.jPlayer.reservedEvent = "ready resize error warning";

	// Events generated by jPlayer
	$.jPlayer.event = {
		ready: "jPlayer_ready",
		resize: "jPlayer_resize", // Not implemented.
		error: "jPlayer_error", // Event error code in event.jPlayer.error.type. See $.jPlayer.error
		warning: "jPlayer_warning", // Event warning code in event.jPlayer.warning.type. See $.jPlayer.warning

		// Other events match HTML5 spec.
		loadstart: "jPlayer_loadstart",
		progress: "jPlayer_progress",
		suspend: "jPlayer_suspend",
		abort: "jPlayer_abort",
		emptied: "jPlayer_emptied",
		stalled: "jPlayer_stalled",
		play: "jPlayer_play",
		pause: "jPlayer_pause",
		loadedmetadata: "jPlayer_loadedmetadata",
		loadeddata: "jPlayer_loadeddata",
		waiting: "jPlayer_waiting",
		playing: "jPlayer_playing",
		canplay: "jPlayer_canplay",
		canplaythrough: "jPlayer_canplaythrough",
		seeking: "jPlayer_seeking",
		seeked: "jPlayer_seeked",
		timeupdate: "jPlayer_timeupdate",
		ended: "jPlayer_ended",
		ratechange: "jPlayer_ratechange",
		durationchange: "jPlayer_durationchange",
		volumechange: "jPlayer_volumechange"
	};

	$.jPlayer.htmlEvent = [ // These HTML events are bubbled through to the jPlayer event, without any internal action.
		"loadstart",
		// "progress", // jPlayer uses internally before bubbling.
		// "suspend", // jPlayer uses internally before bubbling.
		"abort",
		// "error", // jPlayer uses internally before bubbling.
		"emptied",
		"stalled",
		// "play", // jPlayer uses internally before bubbling.
		// "pause", // jPlayer uses internally before bubbling.
		"loadedmetadata",
		"loadeddata",
		// "waiting", // jPlayer uses internally before bubbling.
		// "playing", // jPlayer uses internally before bubbling.
		// "canplay", // jPlayer fixes the volume (for Chrome) before bubbling.
		"canplaythrough",
		// "seeking", // jPlayer uses internally before bubbling.
		// "seeked", // jPlayer uses internally before bubbling.
		// "timeupdate", // jPlayer uses internally before bubbling.
		// "ended", // jPlayer uses internally before bubbling.
		"ratechange"
		// "durationchange" // jPlayer uses internally before bubbling.
		// "volumechange" // Handled by jPlayer in volume() method, primarily due to the volume fix (for Chrome) in the canplay event. [*] Need to review whether the latest Chrome still needs the fix sometime.
	];

	$.jPlayer.pause = function() {
		// $.each($.jPlayer.instances, function(i, element) {
		$.each($.jPlayer.prototype.instances, function(i, element) {
			if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event.
				element.jPlayer("pause");
			}
		});
	};
	
	$.jPlayer.timeFormat = {
		showHour: false,
		showMin: true,
		showSec: true,
		padHour: false,
		padMin: true,
		padSec: true,
		sepHour: ":",
		sepMin: ":",
		sepSec: ""
	};

	$.jPlayer.convertTime = function(s) {
		var myTime = new Date(s * 1000);
		var hour = myTime.getUTCHours();
		var min = myTime.getUTCMinutes();
		var sec = myTime.getUTCSeconds();
		var strHour = ($.jPlayer.timeFormat.padHour && hour < 10) ? "0" + hour : hour;
		var strMin = ($.jPlayer.timeFormat.padMin && min < 10) ? "0" + min : min;
		var strSec = ($.jPlayer.timeFormat.padSec && sec < 10) ? "0" + sec : sec;
		return (($.jPlayer.timeFormat.showHour) ? strHour + $.jPlayer.timeFormat.sepHour : "") + (($.jPlayer.timeFormat.showMin) ? strMin + $.jPlayer.timeFormat.sepMin : "") + (($.jPlayer.timeFormat.showSec) ? strSec + $.jPlayer.timeFormat.sepSec : "");
	};

	// Adapting jQuery 1.4.4 code for jQuery.browser. Required since jQuery 1.3.2 does not detect Chrome as webkit.
	$.jPlayer.uaBrowser = function( userAgent ) {
		var ua = userAgent.toLowerCase();

		// Useragent RegExp
		var rwebkit = /(webkit)[ \/]([\w.]+)/;
		var ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/;
		var rmsie = /(msie) ([\w.]+)/;
		var rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/;

		var match = rwebkit.exec( ua ) ||
			ropera.exec( ua ) ||
			rmsie.exec( ua ) ||
			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
			[];

		return { browser: match[1] || "", version: match[2] || "0" };
	};

	// Platform sniffer for detecting mobile devices
	$.jPlayer.uaPlatform = function( userAgent ) {
		var ua = userAgent.toLowerCase();

		// Useragent RegExp
		var rplatform = /(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/;
		var rtablet = /(ipad|playbook)/;
		var randroid = /(android)/;
		var rmobile = /(mobile)/;

		var platform = rplatform.exec( ua ) || [];
		var tablet = rtablet.exec( ua ) ||
			!rmobile.exec( ua ) && randroid.exec( ua ) ||
			[];

		return { platform: platform[1] || "", tablet: tablet[1] || "" };
	};

	$.jPlayer.browser = {
	};
	$.jPlayer.platform = {
	};

	var browserMatch = $.jPlayer.uaBrowser(navigator.userAgent);
	if ( browserMatch.browser ) {
		$.jPlayer.browser[ browserMatch.browser ] = true;
		$.jPlayer.browser.version = browserMatch.version;
	}
	var platformMatch = $.jPlayer.uaPlatform(navigator.userAgent);
	if ( platformMatch.platform ) {
		$.jPlayer.platform[ platformMatch.platform ] = true;
		$.jPlayer.platform.mobile = !platformMatch.tablet;
		$.jPlayer.platform.tablet = !!platformMatch.tablet;
	}

	$.jPlayer.prototype = {
		count: 0, // Static Variable: Change it via prototype.
		version: { // Static Object
			script: "2.0.15",
			needFlash: "2.0.9",
			flash: "unknown"
		},
		options: { // Instanced in $.jPlayer() constructor
			swfPath: "/sites/all/themes/wire/js/circleplayer/js", // Path to Jplayer.swf. Can be relative, absolute or server root relative.
			solution: "html, flash", // Valid solutions: html, flash. Order defines priority. 1st is highest,
			supplied: "mp3", // Defines which formats jPlayer will try and support and the priority by the order. 1st is highest,
			preload: 'metadata',  // HTML5 Spec values: none, metadata, auto.
			volume: 0.8, // The volume. Number 0 to 1.
			muted: false,
			wmode: "window", // Default Flash wmode is: window.  Valid wmode: transparent, opaque, direct, gpu
			backgroundColor: "#000000", // To define the jPlayer div and Flash background color.
			cssSelectorAncestor: "#jp_container_1",
			cssSelector: { // * denotes properties that should only be required when video media type required. _cssSelector() would require changes to enable splitting these into Audio and Video defaults.
				videoPlay: ".jp-video-play", // *
				play: ".jp-play",
				pause: ".jp-pause",
				stop: ".jp-stop",
				seekBar: ".jp-seek-bar",
				playBar: ".jp-play-bar",
				mute: ".jp-mute",
				unmute: ".jp-unmute",
				volumeBar: ".jp-volume-bar",
				volumeBarValue: ".jp-volume-bar-value",
				currentTime: ".jp-current-time",
				duration: ".jp-duration",
				fullScreen: ".jp-full-screen", // *
				restoreScreen: ".jp-restore-screen" // *
			},
			fullScreen: false,
			// globalVolume: false, // Not implemented: Set to make volume changes affect all jPlayer instances
			// globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances
			idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \
			noConflict: "jQuery",
			emulateHtml: false, // Emulates the HTML5 Media element on the jPlayer element.
			errorAlerts: false,
			warningAlerts: false
		},
		optionsAudio: {
			size: {
				width: "0px",
				height: "0px",
				cssClass: ""
			},
			sizeFull: {
				width: "0px",
				height: "0px",
				cssClass: ""
			}
		},
		optionsVideo: {
			size: {
				width: "480px",
				height: "270px",
				cssClass: "jp-video-270p"
			},
			sizeFull: {
				width: "100%",
				height: "90%",
				cssClass: "jp-video-full"
			}
		},
		instances: {}, // Static Object
		status: { // Instanced in _init()
			src: "",
			media: {},
			paused: true,
			format: {},
			formatType: "",
			waitForPlay: true, // Same as waitForLoad except in case where preloading.
			waitForLoad: true,
			srcSet: false,
			video: false, // True if playing a video
			seekPercent: 0,
			currentPercentRelative: 0,
			currentPercentAbsolute: 0,
			currentTime: 0,
			duration: 0,
			readyState: 0,
			networkState: 0,
			playbackRate: 1,
			ended: 0

/*		Persistant status properties created dynamically at _init():
			width
			height
			cssClass
*/
		},

		internal: { // Instanced in _init()
			ready: false
			// instance: undefined,
			// domNode: undefined,
			// htmlDlyCmdId: undefined
		},
		solution: { // Static Object: Defines the solutions built in jPlayer.
			html: true,
			flash: true
		},
		// 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"')
		format: { // Static Object
			mp3: {
				codec: 'audio/mpeg; codecs="mp3"',
				flashCanPlay: true,
				media: 'audio'
			},
			m4a: { // AAC / MP4
				codec: 'audio/mp4; codecs="mp4a.40.2"',
				flashCanPlay: true,
				media: 'audio'
			},
			oga: { // OGG
				codec: 'audio/ogg; codecs="vorbis"',
				flashCanPlay: false,
				media: 'audio'
			},
			wav: { // PCM
				codec: 'audio/wav; codecs="1"',
				flashCanPlay: false,
				media: 'audio'
			},
			webma: { // WEBM
				codec: 'audio/webm; codecs="vorbis"',
				flashCanPlay: false,
				media: 'audio'
			},
			fla: { // FLV / F4A
				codec: 'audio/x-flv',
				flashCanPlay: true,
				media: 'audio'
			},
			m4v: { // H.264 / MP4
				codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
				flashCanPlay: true,
				media: 'video'
			},
			ogv: { // OGG
				codec: 'video/ogg; codecs="theora, vorbis"',
				flashCanPlay: false,
				media: 'video'
			},
			webmv: { // WEBM
				codec: 'video/webm; codecs="vorbis, vp8"',
				flashCanPlay: false,
				media: 'video'
			},
			flv: { // FLV / F4V
				codec: 'video/x-flv',
				flashCanPlay: true,
				media: 'video'
			}
		},
		_init: function() {
			var self = this;
			
			this.element.empty();
			
			this.status = $.extend({}, this.status); // Copy static to unique instance.
			this.internal = $.extend({}, this.internal); // Copy static to unique instance.

			this.internal.domNode = this.element.get(0);

			this.formats = []; // Array based on supplied string option. Order defines priority.
			this.solutions = []; // Array based on solution string option. Order defines priority.
			this.require = {}; // Which media types are required: video, audio.
			
			this.htmlElement = {}; // DOM elements created by jPlayer
			this.html = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
			this.html.audio = {};
			this.html.video = {};
			this.flash = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
			
			this.css = {};
			this.css.cs = {}; // Holds the css selector strings
			this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method)

			this.ancestorJq = []; // Holds jQuery selector of cssSelectorAncestor. Init would use $() instead of [], but it is only 1.4+

			this.options.volume = this._limitValue(this.options.volume, 0, 1); // Limit volume value's bounds.

			// Create the formats array, with prority based on the order of the supplied formats string
			$.each(this.options.supplied.toLowerCase().split(","), function(index1, value1) {
				var format = value1.replace(/^\s+|\s+$/g, ""); //trim
				if(self.format[format]) { // Check format is valid.
					var dupFound = false;
					$.each(self.formats, function(index2, value2) { // Check for duplicates
						if(format === value2) {
							dupFound = true;
							return false;
						}
					});
					if(!dupFound) {
						self.formats.push(format);
					}
				}
			});

			// Create the solutions array, with prority based on the order of the solution string
			$.each(this.options.solution.toLowerCase().split(","), function(index1, value1) {
				var solution = value1.replace(/^\s+|\s+$/g, ""); //trim
				if(self.solution[solution]) { // Check solution is valid.
					var dupFound = false;
					$.each(self.solutions, function(index2, value2) { // Check for duplicates
						if(solution === value2) {
							dupFound = true;
							return false;
						}
					});
					if(!dupFound) {
						self.solutions.push(solution);
					}
				}
			});

			this.internal.instance = "jp_" + this.count;
			this.instances[this.internal.instance] = this.element;

			// Check the jPlayer div has an id and create one if required. Important for Flash to know the unique id for comms.
			if(this.element.attr("id") === "") {
				this.element.attr("id", this.options.idPrefix + "_jplayer_" + this.count);
			}

			this.internal.self = $.extend({}, {
				id: this.element.attr("id"),
				jq: this.element
			});
			this.internal.audio = $.extend({}, {
				id: this.options.idPrefix + "_audio_" + this.count,
				jq: undefined
			});
			this.internal.video = $.extend({}, {
				id: this.options.idPrefix + "_video_" + this.count,
				jq: undefined
			});
			this.internal.flash = $.extend({}, {
				id: this.options.idPrefix + "_flash_" + this.count,
				jq: undefined,
				swf: this.options.swfPath + ((this.options.swfPath !== "" && this.options.swfPath.slice(-1) !== "/") ? "/" : "") + "Jplayer.swf"
			});
			this.internal.poster = $.extend({}, {
				id: this.options.idPrefix + "_poster_" + this.count,
				jq: undefined
			});

			// Register listeners defined in the constructor
			$.each($.jPlayer.event, function(eventName,eventType) {
				if(self.options[eventName] !== undefined) {
					self.element.bind(eventType + ".jPlayer", self.options[eventName]); // With .jPlayer namespace.
					self.options[eventName] = undefined; // Destroy the handler pointer copy on the options. Reason, events can be added/removed in other ways so this could be obsolete and misleading.
				}
			});

			// Determine if we require solutions for audio, video or both media types.
			this.require.audio = false;
			this.require.video = false;
			$.each(this.formats, function(priority, format) {
				self.require[self.format[format].media] = true;
			});

			// Now required types are known, finish the options default settings.
			if(this.require.video) {
				this.options = $.extend(true, {},
					this.optionsVideo,
					this.options
				);
			} else {
				this.options = $.extend(true, {},
					this.optionsAudio,
					this.options
				);
			}
			this._setSize(); // update status and jPlayer element size

			// Create the poster image.
			this.htmlElement.poster = document.createElement('img');
			this.htmlElement.poster.id = this.internal.poster.id;
			this.htmlElement.poster.onload = function() { // Note that this did not work on Firefox 3.6: poster.addEventListener("onload", function() {}, false); Did not investigate x-browser.
				if(!self.status.video || self.status.waitForPlay) {
					self.internal.poster.jq.show();
				}
			};
			this.element.append(this.htmlElement.poster);
			this.internal.poster.jq = $("#" + this.internal.poster.id);
			this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height});
			this.internal.poster.jq.hide();
			
			// Generate the required media elements
			this.html.audio.available = false;
			if(this.require.audio) { // If a supplied format is audio
				this.htmlElement.audio = document.createElement('audio');
				this.htmlElement.audio.id = this.internal.audio.id;
				this.html.audio.available = !!this.htmlElement.audio.canPlayType;
			}
			this.html.video.available = false;
			if(this.require.video) { // If a supplied format is video
				this.htmlElement.video = document.createElement('video');
				this.htmlElement.video.id = this.internal.video.id;
				this.html.video.available = !!this.htmlElement.video.canPlayType;
			}

			this.flash.available = this._checkForFlash(10);

			this.html.canPlay = {};
			this.flash.canPlay = {};
			$.each(this.formats, function(priority, format) {
				self.html.canPlay[format] = self.html[self.format[format].media].available && "" !== self.htmlElement[self.format[format].media].canPlayType(self.format[format].codec);
				self.flash.canPlay[format] = self.format[format].flashCanPlay && self.flash.available;
			});
			this.html.desired = false;
			this.flash.desired = false;
			$.each(this.solutions, function(solutionPriority, solution) {
				if(solutionPriority === 0) {
					self[solution].desired = true;
				} else {
					var audioCanPlay = false;
					var videoCanPlay = false;
					$.each(self.formats, function(formatPriority, format) {
						if(self[self.solutions[0]].canPlay[format]) { // The other solution can play
							if(self.format[format].media === 'video') {
								videoCanPlay = true;
							} else {
								audioCanPlay = true;
							}
						}
					});
					self[solution].desired = (self.require.audio && !audioCanPlay) || (self.require.video && !videoCanPlay);
				}
			});
			// This is what jPlayer will support, based on solution and supplied.
			this.html.support = {};
			this.flash.support = {};
			$.each(this.formats, function(priority, format) {
				self.html.support[format] = self.html.canPlay[format] && self.html.desired;
				self.flash.support[format] = self.flash.canPlay[format] && self.flash.desired;
			});
			// If jPlayer is supporting any format in a solution, then the solution is used.
			this.html.used = false;
			this.flash.used = false;
			$.each(this.solutions, function(solutionPriority, solution) {
				$.each(self.formats, function(formatPriority, format) {
					if(self[solution].support[format]) {
						self[solution].used = true;
						return false;
					}
				});
			});

			// Init solution active state and the event gates to false.
			this.html.active = false;
			this.html.audio.gate = false;
			this.html.video.gate = false;
			this.flash.active = false;
			this.flash.gate = false;

			// Set up the css selectors for the control and feedback entities.
			this._cssSelectorAncestor(this.options.cssSelectorAncestor);
			
			// If neither html nor flash are being used by this browser, then media playback is not possible. Trigger an error event.
			if(!(this.html.used || this.flash.used)) {
				this._error( {
					type: $.jPlayer.error.NO_SOLUTION, 
					context: "{solution:'" + this.options.solution + "', supplied:'" + this.options.supplied + "'}",
					message: $.jPlayer.errorMsg.NO_SOLUTION,
					hint: $.jPlayer.errorHint.NO_SOLUTION
				});
			}

			// Add the flash solution if it is being used.
			if(this.flash.used) {
				var htmlObj,
				flashVars = 'jQuery=' + encodeURI(this.options.noConflict) + '&id=' + encodeURI(this.internal.self.id) + '&vol=' + this.options.volume + '&muted=' + this.options.muted;

				// Code influenced by SWFObject 2.2: http://code.google.com/p/swfobject/
				// Non IE browsers have an initial Flash size of 1 by 1 otherwise the wmode affected the Flash ready event. 

				if($.browser.msie && Number($.browser.version) <= 8) {
					var objStr = '<object id="' + this.internal.flash.id + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0"></object>';

					var paramStr = [
						'<param name="movie" value="' + this.internal.flash.swf + '" />',
						'<param name="FlashVars" value="' + flashVars + '" />',
						'<param name="allowScriptAccess" value="always" />',
						'<param name="bgcolor" value="' + this.options.backgroundColor + '" />',
						'<param name="wmode" value="' + this.options.wmode + '" />'
					];

					htmlObj = document.createElement(objStr);
					for(var i=0; i < paramStr.length; i++) {
						htmlObj.appendChild(document.createElement(paramStr[i]));
					}
				} else {
					var createParam = function(el, n, v) {
						var p = document.createElement("param");
						p.setAttribute("name", n);	
						p.setAttribute("value", v);
						el.appendChild(p);
					};

					htmlObj = document.createElement("object");
					htmlObj.setAttribute("id", this.internal.flash.id);
					htmlObj.setAttribute("data", this.internal.flash.swf);
					htmlObj.setAttribute("type", "application/x-shockwave-flash");
					htmlObj.setAttribute("width", "1"); // Non-zero
					htmlObj.setAttribute("height", "1"); // Non-zero
					createParam(htmlObj, "flashvars", flashVars);
					createParam(htmlObj, "allowscriptaccess", "always");
					createParam(htmlObj, "bgcolor", this.options.backgroundColor);
					createParam(htmlObj, "wmode", this.options.wmode);
				}

				this.element.append(htmlObj);
				this.internal.flash.jq = $(htmlObj);
			}
			
			// Add the HTML solution if being used.
			if(this.html.used) {

				// The HTML Audio handlers
				if(this.html.audio.available) {
					this._addHtmlEventListeners(this.htmlElement.audio, this.html.audio);
					this.element.append(this.htmlElement.audio);
					this.internal.audio.jq = $("#" + this.internal.audio.id);
				}

				// The HTML Video handlers
				if(this.html.video.available) {
					this._addHtmlEventListeners(this.htmlElement.video, this.html.video);
					this.element.append(this.htmlElement.video);
					this.internal.video.jq = $("#" + this.internal.video.id);
					this.internal.video.jq.css({'width':'0px', 'height':'0px'}); // Using size 0x0 since a .hide() causes issues in iOS
				}
			}

			// Create the bridge that emulates the HTML Media element on the jPlayer DIV
			if( this.options.emulateHtml ) {
				this._emulateHtmlBridge();
			}

			if(this.html.used && !this.flash.used) { // If only HTML, then emulate flash ready() call after 100ms.
				window.setTimeout( function() {
					self.internal.ready = true;
					self.version.flash = "n/a";
					self._trigger($.jPlayer.event.ready);
				}, 100);
			}

			this._updateInterface();
			this._updateButtons(false);
			this._updateVolume(this.options.volume);
			this._updateMute(this.options.muted);
			if(this.css.jq.videoPlay.length) {
				this.css.jq.videoPlay.hide();
			}
			$.jPlayer.prototype.count++; // Change static variable via prototype.
		},
		destroy: function() {
			// MJP: The background change remains. Would need to store the original to restore it correctly.

			// Reset the interface, remove seeking effect and times.
			this._resetStatus();
			this._updateInterface();
			this._seeked();
			if(this.css.jq.currentTime.length) {
				this.css.jq.currentTime.text("");
			}
			if(this.css.jq.duration.length) {
				this.css.jq.duration.text("");
			}

			if(this.status.srcSet) { // Or you get a bogus error event
				this.pause(); // Pauses the media and clears any delayed commands used in the HTML solution.
			}
			$.each(this.css.jq, function(fn, jq) { // Remove any bindings from the interface controls.
				// Check selector is valid before trying to execute method.
				if(jq.length) {
					jq.unbind(".jPlayer");
				}
			});
			if( this.options.emulateHtml ) {
				this._destroyHtmlBridge();
			}
			this.element.removeData("jPlayer"); // Remove jPlayer data
			this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor
			this.element.empty(); // Remove the inserted child elements
			
			this.instances[this.internal.instance] = undefined; // Clear the instance on the static instance object
		},
		enable: function() { // Plan to implement
			// options.disabled = false
		},
		disable: function () { // Plan to implement
			// options.disabled = true
		},
		_addHtmlEventListeners: function(mediaElement, entity) {
			var self = this;
			mediaElement.preload = this.options.preload;
			mediaElement.muted = this.options.muted;
			mediaElement.volume = this.options.volume;

			// Create the event listeners
			// Only want the active entity to affect jPlayer and bubble events.
			// Using entity.gate so that object is referenced and gate property always current
			
			mediaElement.addEventListener("progress", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._getHtmlStatus(mediaElement);
					self._updateInterface();
					self._trigger($.jPlayer.event.progress);
				}
			}, false);
			mediaElement.addEventListener("timeupdate", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._getHtmlStatus(mediaElement);
					self._updateInterface();
					self._trigger($.jPlayer.event.timeupdate);
				}
			}, false);
			mediaElement.addEventListener("durationchange", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self.status.duration = this.duration;
					self._getHtmlStatus(mediaElement);
					self._updateInterface();
					self._trigger($.jPlayer.event.durationchange);
				}
			}, false);
			mediaElement.addEventListener("play", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._updateButtons(true);
					self._trigger($.jPlayer.event.play);
				}
			}, false);
			mediaElement.addEventListener("playing", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._updateButtons(true);
					self._seeked();
					self._trigger($.jPlayer.event.playing);
				}
			}, false);
			mediaElement.addEventListener("pause", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._updateButtons(false);
					self._trigger($.jPlayer.event.pause);
				}
			}, false);
			mediaElement.addEventListener("waiting", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._seeking();
					self._trigger($.jPlayer.event.waiting);
				}
			}, false);
			mediaElement.addEventListener("canplay", function() {
				if(entity.gate && !self.status.waitForLoad) {
					mediaElement.volume = self._volumeFix(self.options.volume);
					self._trigger($.jPlayer.event.canplay);
				}
			}, false);
			mediaElement.addEventListener("seeking", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._seeking();
					self._trigger($.jPlayer.event.seeking);
				}
			}, false);
			mediaElement.addEventListener("seeked", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._seeked();
					self._trigger($.jPlayer.event.seeked);
				}
			}, false);
			mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture.
				if(entity.gate && !self.status.waitForLoad) {
					self._seeked();
					self._trigger($.jPlayer.event.suspend);
				}
			}, false);
			mediaElement.addEventListener("ended", function() {
				if(entity.gate && !self.status.waitForLoad) {
					// Order of the next few commands are important. Change the time and then pause.
					// Solves a bug in Firefox, where issuing pause 1st causes the media to play from the start. ie., The pause is ignored.
					if(!$.jPlayer.browser.webkit) { // Chrome crashes if you do this in conjunction with a setMedia command in an ended event handler. ie., The playlist demo.
						self.htmlElement.media.currentTime = 0; // Safari does not care about this command. ie., It works with or without this line. (Both Safari and Chrome are Webkit.)
					}
					self.htmlElement.media.pause(); // Pause otherwise a click on the progress bar will play from that point, when it shouldn't, since it stopped playback.
					self._updateButtons(false);
					self._getHtmlStatus(mediaElement, true); // With override true. Otherwise Chrome leaves progress at full.
					self._updateInterface();
					self._trigger($.jPlayer.event.ended);
				}
			}, false);
			mediaElement.addEventListener("error", function() {
				if(entity.gate && !self.status.waitForLoad) {
					self._updateButtons(false);
					self._seeked();
					if(self.status.srcSet) { // Deals with case of clearMedia() causing an error event.
						clearTimeout(self.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution.
						self.status.waitForLoad = true; // Allows the load operation to try again.
						self.status.waitForPlay = true; // Reset since a play was captured.
						if(self.status.video) {
							self.internal.video.jq.css({'width':'0px', 'height':'0px'});
						}
						if(self._validString(self.status.media.poster)) {
							self.internal.poster.jq.show();
						}
						if(self.css.jq.videoPlay.length) {
							self.css.jq.videoPlay.show();
						}
						self._error( {
							type: $.jPlayer.error.URL,
							context: self.status.src, // this.src shows absolute urls. Want context to show the url given.
							message: $.jPlayer.errorMsg.URL,
							hint: $.jPlayer.errorHint.URL
						});
					}
				}
			}, false);
			// Create all the other event listeners that bubble up to a jPlayer event from html, without being used by jPlayer.
			$.each($.jPlayer.htmlEvent, function(i, eventType) {
				mediaElement.addEventListener(this, function() {
					if(entity.gate && !self.status.waitForLoad) {
						self._trigger($.jPlayer.event[eventType]);
					}
				}, false);
			});
		},
		_getHtmlStatus: function(media, override) {
			var ct = 0, d = 0, cpa = 0, sp = 0, cpr = 0;

			if(media.duration) { // Fixes the duration bug in iOS, where the durationchange event occurs when media.duration is not always correct.
				this.status.duration = media.duration;
			}
			ct = media.currentTime;
			cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration : 0;
			if((typeof media.seekable === "object") && (media.seekable.length > 0)) {
				sp = (this.status.duration > 0) ? 100 * media.seekable.end(media.seekable.length-1) / this.status.duration : 100;
				cpr = 100 * media.currentTime / media.seekable.end(media.seekable.length-1);
			} else {
				sp = 100;
				cpr = cpa;
			}
			
			if(override) {
				ct = 0;
				cpr = 0;
				cpa = 0;
			}

			this.status.seekPercent = sp;
			this.status.currentPercentRelative = cpr;
			this.status.currentPercentAbsolute = cpa;
			this.status.currentTime = ct;

			this.status.readyState = media.readyState;
			this.status.networkState = media.networkState;
			this.status.playbackRate = media.playbackRate;
			this.status.ended = media.ended;
		},
		_resetStatus: function() {
			this.status = $.extend({}, this.status, $.jPlayer.prototype.status); // Maintains the status properties that persist through a reset.
		},
		_trigger: function(eventType, error, warning) { // eventType always valid as called using $.jPlayer.event.eventType
			var event = $.Event(eventType);
			event.jPlayer = {};
			event.jPlayer.version = $.extend({}, this.version);
			event.jPlayer.options = $.extend(true, {}, this.options); // Deep copy
			event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy
			event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy
			event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy
			if(error) {
				event.jPlayer.error = $.extend({}, error);
			}
			if(warning) {
				event.jPlayer.warning = $.extend({}, warning);
			}
			this.element.trigger(event);
		},
		jPlayerFlashEvent: function(eventType, status) { // Called from Flash
			if(eventType === $.jPlayer.event.ready && !this.internal.ready) {
				this.internal.ready = true;
				this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Once Flash generates the ready event, minimise to zero as it is not affected by wmode anymore.

				this.version.flash = status.version;
				if(this.version.needFlash !== this.version.flash) {
					this._error( {
						type: $.jPlayer.error.VERSION,
						context: this.version.flash,
						message: $.jPlayer.errorMsg.VERSION + this.version.flash,
						hint: $.jPlayer.errorHint.VERSION
					});
				}
				this._trigger(eventType);
			}
			if(this.flash.gate) {
				switch(eventType) {
					case $.jPlayer.event.progress:
						this._getFlashStatus(status);
						this._updateInterface();
						this._trigger(eventType);
						break;
					case $.jPlayer.event.timeupdate:
						this._getFlashStatus(status);
						this._updateInterface();
						this._trigger(eventType);
						break;
					case $.jPlayer.event.play:
						this._seeked();
						this._updateButtons(true);
						this._trigger(eventType);
						break;
					case $.jPlayer.event.pause:
						this._updateButtons(false);
						this._trigger(eventType);
						break;
					case $.jPlayer.event.ended:
						this._updateButtons(false);
						this._trigger(eventType);
						break;
					case $.jPlayer.event.error:
						this.status.waitForLoad = true; // Allows the load operation to try again.
						this.status.waitForPlay = true; // Reset since a play was captured.
						if(this.status.video) {
							this.internal.flash.jq.css({'width':'0px', 'height':'0px'});
						}
						if(this._validString(this.status.media.poster)) {
							this.internal.poster.jq.show();
						}
						if(this.css.jq.videoPlay.length) {
							this.css.jq.videoPlay.show();
						}
						if(this.status.video) { // Set up for another try. Execute before error event.
							this._flash_setVideo(this.status.media);
						} else {
							this._flash_setAudio(this.status.media);
						}
						this._error( {
							type: $.jPlayer.error.URL,
							context:status.src,
							message: $.jPlayer.errorMsg.URL,
							hint: $.jPlayer.errorHint.URL
						});
						break;
					case $.jPlayer.event.seeking:
						this._seeking();
						this._trigger(eventType);
						break;
					case $.jPlayer.event.seeked:
						this._seeked();
						this._trigger(eventType);
						break;
					case $.jPlayer.event.ready:
						// The ready event is handled outside the switch statement.
						// Captured here otherwise 2 ready events would be generated if the ready event handler used setMedia.
						break;
					default:
						this._trigger(eventType);
				}
			}
			return false;
		},
		_getFlashStatus: function(status) {
			this.status.seekPercent = status.seekPercent;
			this.status.currentPercentRelative = status.currentPercentRelative;
			this.status.currentPercentAbsolute = status.currentPercentAbsolute;
			this.status.currentTime = status.currentTime;
			this.status.duration = status.duration;

			// The Flash does not generate this information in this release
			this.status.readyState = 4; // status.readyState;
			this.status.networkState = 0; // status.networkState;
			this.status.playbackRate = 1; // status.playbackRate;
			this.status.ended = false; // status.ended;
		},
		_updateButtons: function(playing) {
			this.status.paused = !playing;
			if(this.css.jq.play.length && this.css.jq.pause.length) {
				if(playing) {
					this.css.jq.play.hide();
					this.css.jq.pause.show();
				} else {
					this.css.jq.play.show();
					this.css.jq.pause.hide();
				}
			}
		},
		_updateInterface: function() {
			if(this.css.jq.seekBar.length) {
				this.css.jq.seekBar.width(this.status.seekPercent+"%");
			}
			if(this.css.jq.playBar.length) {
				this.css.jq.playBar.width(this.status.currentPercentRelative+"%");
			}
			if(this.css.jq.currentTime.length) {
				this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.currentTime));
			}
			if(this.css.jq.duration.length) {
				this.css.jq.duration.text($.jPlayer.convertTime(this.status.duration));
			}
		},
		_seeking: function() {
			if(this.css.jq.seekBar.length) {
				this.css.jq.seekBar.addClass("jp-seeking-bg");
			}
		},
		_seeked: function() {
			if(this.css.jq.seekBar.length) {
				this.css.jq.seekBar.removeClass("jp-seeking-bg");
			}
		},
		setMedia: function(media) {
		
			/*	media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats.
			 *	media.poster = String: Video poster URL.
			 *	media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file
			 *	media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file
			 *	media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often.
			 */
			
			var self = this;
			
			this._seeked();
			clearTimeout(this.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution.

			// Store the current html gates, since we need for clearMedia() conditions.
			var audioGate = this.html.audio.gate;
			var videoGate = this.html.video.gate;

			var supported = false;
			$.each(this.formats, function(formatPriority, format) {
				var isVideo = self.format[format].media === 'video';
				$.each(self.solutions, function(solutionPriority, solution) {
					if(self[solution].support[format] && self._validString(media[format])) { // Format supported in solution and url given for format.
						var isHtml = solution === 'html';
						
						if(isVideo) {
							if(isHtml) {
								self.html.audio.gate = false;
								self.html.video.gate = true;
								self.flash.gate = false;
							} else {
								self.html.audio.gate = false;
								self.html.video.gate = false;
								self.flash.gate = true;
							}
						} else {
							if(isHtml) {
								self.html.audio.gate = true;
								self.html.video.gate = false;
								self.flash.gate = false;
							} else {
								self.html.audio.gate = false;
								self.html.video.gate = false;
								self.flash.gate = true;
							}
						}

						// Clear media of the previous solution if:
						//  - it was Flash
						//  - changing from HTML to Flash
						//  - the HTML solution media type (audio or video) remained the same.
						// Note that, we must be careful with clearMedia() on iPhone, otherwise clearing the video when changing to audio corrupts the built in video player.
						if(self.flash.active || (self.html.active && self.flash.gate) || (audioGate === self.html.audio.gate && videoGate === self.html.video.gate)) {
							self.clearMedia();
						} else if(audioGate !== self.html.audio.gate && videoGate !== self.html.video.gate) { // If switching between html elements
							self._html_pause();
							// Hide the video if it was being used.
							if(self.status.video) {
								self.internal.video.jq.css({'width':'0px', 'height':'0px'});
							}
							self._resetStatus(); // Since clearMedia usually does this. Execute after status.video useage.
						}

						if(isVideo) {
							if(isHtml) {
								self._html_setVideo(media);
								self.html.active = true;
								self.flash.active = false;
							} else {
								self._flash_setVideo(media);
								self.html.active = false;
								self.flash.active = true;
							}
							if(self.css.jq.videoPlay.length) {
								self.css.jq.videoPlay.show();
							}
							self.status.video = true;
						} else {
							if(isHtml) {
								self._html_setAudio(media);
								self.html.active = true;
								self.flash.active = false;
							} else {
								self._flash_setAudio(media);
								self.html.active = false;
								self.flash.active = true;
							}
							if(self.css.jq.videoPlay.length) {
								self.css.jq.videoPlay.hide();
							}
							self.status.video = false;
						}
						
						supported = true;
						return false; // Exit $.each
					}
				});
				if(supported) {
					return false; // Exit $.each
				}
			});

			if(supported) {
				// Set poster after the possible clearMedia() command above. IE had issues since the IMG onload event occurred immediately when cached. ie., The clearMedia() hide the poster.
				if(this._validString(media.poster)) {
					if(this.htmlElement.poster.src !== media.poster) { // Since some browsers do not generate img onload event.
						this.htmlElement.poster.src = media.poster;
					} else {
						this.internal.poster.jq.show();
					}
				} else {
					this.internal.poster.jq.hide(); // Hide if not used, since clearMedia() does not always occur above. ie., HTML audio <-> video switching.
				}
				this.status.srcSet = true;
				this.status.media = $.extend({}, media);
				this._updateButtons(false);
				this._updateInterface();
			} else { // jPlayer cannot support any formats provided in this browser
				// Pause here if old media could be playing. Otherwise, playing media being changed to bad media would leave the old media playing.
				if(this.status.srcSet && !this.status.waitForPlay) {
					this.pause();
				}
				// Reset all the control flags
				this.html.audio.gate = false;
				this.html.video.gate = false;
				this.flash.gate = false;
				this.html.active = false;
				this.flash.active = false;
				// Reset status and interface.
				this._resetStatus();
				this._updateInterface();
				this._updateButtons(false);
				// Hide the any old media
				this.internal.poster.jq.hide();
				if(this.html.used && this.require.video) {
					this.internal.video.jq.css({'width':'0px', 'height':'0px'});
				}
				if(this.flash.used) {
					this.internal.flash.jq.css({'width':'0px', 'height':'0px'});
				}
				// Send an error event
				this._error( {
					type: $.jPlayer.error.NO_SUPPORT,
					context: "{supplied:'" + this.options.supplied + "'}",
					message: $.jPlayer.errorMsg.NO_SUPPORT,
					hint: $.jPlayer.errorHint.NO_SUPPORT
				});
			}
		},
		clearMedia: function() {
			this._resetStatus();
			this._updateButtons(false);

			this.internal.poster.jq.hide();

			clearTimeout(this.internal.htmlDlyCmdId);

			if(this.html.active) {
				this._html_clearMedia();
			} else if(this.flash.active) {
				this._flash_clearMedia();
			}
		},
		load: function() {
			if(this.status.srcSet) {
				if(this.html.active) {
					this._html_load();
				} else if(this.flash.active) {
					this._flash_load();
				}
			} else {
				this._urlNotSetError("load");
			}
		},
		play: function(time) {
			time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler
			if(this.status.srcSet) {
				if(this.html.active) {
					this._html_play(time);
				} else if(this.flash.active) {
					this._flash_play(time);
				}
			} else {
				this._urlNotSetError("play");
			}
		},
		videoPlay: function(e) { // Handles clicks on the play button over the video poster
			this.play();
		},
		pause: function(time) {
			time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler
			if(this.status.srcSet) {
				if(this.html.active) {
					this._html_pause(time);
				} else if(this.flash.active) {
					this._flash_pause(time);
				}
			} else {
				this._urlNotSetError("pause");
			}
		},
		pauseOthers: function() {
			var self = this;
			$.each(this.instances, function(i, element) {
				if(self.element !== element) { // Do not this instance.
					if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event.
						element.jPlayer("pause");
					}
				}
			});
		},
		stop: function() {
			if(this.status.srcSet) {
				if(this.html.active) {
					this._html_pause(0);
				} else if(this.flash.active) {
					this._flash_pause(0);
				}
			} else {
				this._urlNotSetError("stop");
			}
		},
		playHead: function(p) {
			p = this._limitValue(p, 0, 100);
			if(this.status.srcSet) {
				if(this.html.active) {
					this._html_playHead(p);
				} else if(this.flash.active) {
					this._flash_playHead(p);
				}
			} else {
				this._urlNotSetError("playHead");
			}
		},
		_muted: function(muted) {
			this.options.muted = muted;
			if(this.html.used) {
				this._html_mute(muted);
			}
			if(this.flash.used) {
				this._flash_mute(muted);
			}
			this._updateMute(muted);
			this._updateVolume(this.options.volume);
			this._trigger($.jPlayer.event.volumechange);
		},
		mute: function(mute) { // mute is either: undefined (true), an event object (true) or a boolean (muted).
			mute = mute === undefined ? true : !!mute;
			this._muted(mute);
		},
		unmute: function(unmute) { // unmute is either: undefined (true), an event object (true) or a boolean (!muted).
			unmute = unmute === undefined ? true : !!unmute;
			this._muted(!unmute);
		},
		_updateMute: function(mute) {
			if(this.css.jq.mute.length && this.css.jq.unmute.length) {
				if(mute) {
					this.css.jq.mute.hide();
					this.css.jq.unmute.show();
				} else {
					this.css.jq.mute.show();
					this.css.jq.unmute.hide();
				}
			}
		},
		volume: function(v) {
			v = this._limitValue(v, 0, 1);
			this.options.volume = v;

			if(this.html.used) {
				this._html_volume(v);
			}
			if(this.flash.used) {
				this._flash_volume(v);
			}
			this._updateVolume(v);
			this._trigger($.jPlayer.event.volumechange);
		},
		volumeBar: function(e) { // Handles clicks on the volumeBar
			if(!this.options.muted && this.css.jq.volumeBar.length) { // Ignore clicks when muted
				var offset = this.css.jq.volumeBar.offset();
				var x = e.pageX - offset.left;
				var w = this.css.jq.volumeBar.width();
				var v = x/w;
				this.volume(v);
			}
		},
		volumeBarValue: function(e) { // Handles clicks on the volumeBarValue
			this.volumeBar(e);
		},
		_updateVolume: function(v) {
			v = this.options.muted ? 0 : v;
			if(this.css.jq.volumeBarValue.length) {
				this.css.jq.volumeBarValue.width((v*100)+"%");
			}
		},
		_volumeFix: function(v) { // Need to review if this is still necessary on latest Chrome
			var rnd = 0.001 * Math.random(); // Fix for Chrome 4: Fix volume being set multiple times before playing bug.
			var fix = (v < 0.5) ? rnd : -rnd; // Fix for Chrome 4: Solves volume change before play bug. (When new vol == old vol Chrome 4 does nothing!)
			return (v + fix); // Fix for Chrome 4: Event solves initial volume not being set correctly.
		},
		_cssSelectorAncestor: function(ancestor) {
			var self = this;
			this.options.cssSelectorAncestor = ancestor;
			this._removeUiClass();
			this.ancestorJq = ancestor ? $(ancestor) : []; // Would use $() instead of [], but it is only 1.4+
			if(ancestor && this.ancestorJq.length !== 1) { // So empty strings do not generate the warning.
				this._warning( {
					type: $.jPlayer.warning.CSS_SELECTOR_COUNT,
					context: ancestor,
					message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.ancestorJq.length + " found for cssSelectorAncestor.",
					hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT
				});
			}
			this._addUiClass();
			$.each(this.options.cssSelector, function(fn, cssSel) {
				self._cssSelector(fn, cssSel);
			});
		},
		_cssSelector: function(fn, cssSel) {
			var self = this;
			if(typeof cssSel === 'string') {
				if($.jPlayer.prototype.options.cssSelector[fn]) {
					if(this.css.jq[fn] && this.css.jq[fn].length) {
						this.css.jq[fn].unbind(".jPlayer");
					}
					this.options.cssSelector[fn] = cssSel;
					this.css.cs[fn] = this.options.cssSelectorAncestor + " " + cssSel;

					if(cssSel) { // Checks for empty string
						this.css.jq[fn] = $(this.css.cs[fn]);
					} else {
						this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set. 
					}

					if(this.css.jq[fn].length) {
						var handler = function(e) {
							self[fn](e);
							$(this).blur();
							return false;
						};
						this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace
					}

					if(cssSel && this.css.jq[fn].length !== 1) { // So empty strings do not generate the warning. ie., they just remove the old one.
						this._warning( {
							type: $.jPlayer.warning.CSS_SELECTOR_COUNT,
							context: this.css.cs[fn],
							message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.css.jq[fn].length + " found for " + fn + " method.",
							hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT
						});
					}
				} else {
					this._warning( {
						type: $.jPlayer.warning.CSS_SELECTOR_METHOD,
						context: fn,
						message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD,
						hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD
					});
				}
			} else {
				this._warning( {
					type: $.jPlayer.warning.CSS_SELECTOR_STRING,
					context: cssSel,
					message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING,
					hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING
				});
			}
		},
		seekBar: function(e) { // Handles clicks on the seekBar
			if(this.css.jq.seekBar) {
				var offset = this.css.jq.seekBar.offset();
				var x = e.pageX - offset.left;
				var w = this.css.jq.seekBar.width();
				var p = 100*x/w;
				this.playHead(p);
			}
		},
		playBar: function(e) { // Handles clicks on the playBar
			this.seekBar(e);
		},
		currentTime: function(e) { // Handles clicks on the text
			// Added to avoid errors using cssSelector system for the text
		},
		duration: function(e) { // Handles clicks on the text
			// Added to avoid errors using cssSelector system for the text
		},
		// Options code adapted from ui.widget.js (1.8.7).  Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1.
		option: function(key, value) {
			var options = key;

			 // Enables use: options().  Returns a copy of options object
			if ( arguments.length === 0 ) {
				return $.extend( true, {}, this.options );
			}

			if(typeof key === "string") {
				var keys = key.split(".");

				 // Enables use: options("someOption")  Returns a copy of the option. Supports dot notation.
				if(value === undefined) {

					var opt = $.extend(true, {}, this.options);
					for(var i = 0; i < keys.length; i++) {
						if(opt[keys[i]] !== undefined) {
							opt = opt[keys[i]];
						} else {
							this._warning( {
								type: $.jPlayer.warning.OPTION_KEY,
								context: key,
								message: $.jPlayer.warningMsg.OPTION_KEY,
								hint: $.jPlayer.warningHint.OPTION_KEY
							});
							return undefined;
						}
					}
					return opt;
				}

				 // Enables use: options("someOptionObject", someObject}).  Creates: {someOptionObject:someObject}
				 // Enables use: options("someOption", someValue).  Creates: {someOption:someValue}
				 // Enables use: options("someOptionObject.someOption", someValue).  Creates: {someOptionObject:{someOption:someValue}}

				options = {};
				var opts = options;

				for(var j = 0; j < keys.length; j++) {
					if(j < keys.length - 1) {
						opts[keys[j]] = {};
						opts = opts[keys[j]];
					} else {
						opts[keys[j]] = value;
					}
				}
			}

			 // Otherwise enables use: options(optionObject).  Uses original object (the key)

			this._setOptions(options);

			return this;
		},
		_setOptions: function(options) {
			var self = this;
			$.each(options, function(key, value) { // This supports the 2 level depth that the options of jPlayer has. Would review if we ever need more depth.
				self._setOption(key, value);
			});

			return this;
		},
		_setOption: function(key, value) {
			var self = this;

			// The ability to set options is limited at this time.

			switch(key) {
				case "volume" :
					this.volume(value);
					break;
				case "muted" :
					this._muted(value);
					break;
				case "cssSelectorAncestor" :
					this._cssSelectorAncestor(value); // Set and refresh all associations for the new ancestor.
					break;
				case "cssSelector" :
					$.each(value, function(fn, cssSel) {
						self._cssSelector(fn, cssSel); // NB: The option is set inside this function, after further validity checks.
					});
					break;
				case "fullScreen" :
					if(this.options[key] !== value) { // if changed
						this._removeUiClass();
						this.options[key] = value;
						this._refreshSize();
					}
					break;
				case "size" :
					if(!this.options.fullScreen && this.options[key].cssClass !== value.cssClass) {
						this._removeUiClass();
					}
					this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
					this._refreshSize();
					break;
				case "sizeFull" :
					if(this.options.fullScreen && this.options[key].cssClass !== value.cssClass) {
						this._removeUiClass();
					}
					this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
					this._refreshSize();
					break;
				case "emulateHtml" :
					if(this.options[key] !== value) { // To avoid multiple event handlers being created, if true already.
						this.options[key] = value;
						if(value) {
							this._emulateHtmlBridge();
						} else {
							this._destroyHtmlBridge();
						}
					}
					break;
			}

			return this;
		},
		// End of: (Options code adapted from ui.widget.js)

		_refreshSize: function() {
			this._setSize(); // update status and jPlayer element size
			this._addUiClass(); // update the ui class
			this._updateSize(); // update internal sizes
		},
		_setSize: function() {
			// Determine the current size from the options
			if(this.options.fullScreen) {
				this.status.width = this.options.sizeFull.width;
				this.status.height = this.options.sizeFull.height;
				this.status.cssClass = this.options.sizeFull.cssClass;
			} else {
				this.status.width = this.options.size.width;
				this.status.height = this.options.size.height;
				this.status.cssClass = this.options.size.cssClass;
			}

			// Set the size of the jPlayer area.
			this.element.css({'width': this.status.width, 'height': this.status.height});
		},
		_addUiClass: function() {
			if(this.ancestorJq.length) {
				this.ancestorJq.addClass(this.status.cssClass);
			}
		},
		_removeUiClass: function() {
			if(this.ancestorJq.length) {
				this.ancestorJq.removeClass(this.status.cssClass);
			}
		},
		_updateSize: function() {
			// The poster uses show/hide so can simply resize it.
			this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height});

			// Video html or flash resized if necessary at this time.
			if(!this.status.waitForPlay) {
				if(this.html.active && this.status.video) { // Only if video media
					this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
				}
				else if(this.flash.active) {
					this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height});
				}
			}
		},
		fullScreen: function() {
			this._setOption("fullScreen", true);
		},
		restoreScreen: function() {
			this._setOption("fullScreen", false);
		},
		_html_initMedia: function() {
			if(this.status.srcSet  && !this.status.waitForPlay) {
				this.htmlElement.media.pause();
			}
			if(this.options.preload !== 'none') {
				this._html_load();
			}
			this._trigger($.jPlayer.event.timeupdate); // The flash generates this event for its solution.
		},
		_html_setAudio: function(media) {
			var self = this;
			// Always finds a format due to checks in setMedia()
			$.each(this.formats, function(priority, format) {
				if(self.html.support[format] && media[format]) {
					self.status.src = media[format];
					self.status.format[format] = true;
					self.status.formatType = format;
					return false;
				}
			});
			this.htmlElement.media = this.htmlElement.audio;
			this._html_initMedia();
		},
		_html_setVideo: function(media) {
			var self = this;
			// Always finds a format due to checks in setMedia()
			$.each(this.formats, function(priority, format) {
				if(self.html.support[format] && media[format]) {
					self.status.src = media[format];
					self.status.format[format] = true;
					self.status.formatType = format;
					return false;
				}
			});
			this.htmlElement.media = this.htmlElement.video;
			this._html_initMedia();
		},
		_html_clearMedia: function() {
			if(this.htmlElement.media) {
				if(this.htmlElement.media.id === this.internal.video.id) {
					this.internal.video.jq.css({'width':'0px', 'height':'0px'});
				}
				this.htmlElement.media.pause();
				this.htmlElement.media.src = "";
				this.htmlElement.media.load(); // Stops an old, "in progress" download from continuing the download. Triggers the loadstart, error and emptied events, due to the empty src. Also an abort event if a download was in progress.
			}
		},
		_html_load: function() {
			if(this.status.waitForLoad) {
				this.status.waitForLoad = false;
				this.htmlElement.media.src = this.status.src;
				this.htmlElement.media.load();
			}
			clearTimeout(this.internal.htmlDlyCmdId);
		},
		_html_play: function(time) {
			var self = this;
			this._html_load(); // Loads if required and clears any delayed commands.

			this.htmlElement.media.play(); // Before currentTime attempt otherwise Firefox 4 Beta never loads.

			if(!isNaN(time)) {
				try {
					this.htmlElement.media.currentTime = time;
				} catch(err) {
					this.internal.htmlDlyCmdId = setTimeout(function() {
						self.play(time);
					}, 100);
					return; // Cancel execution and wait for the delayed command.
				}
			}
			this._html_checkWaitForPlay();
		},
		_html_pause: function(time) {
			var self = this;
			
			if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation.
				this._html_load(); // Loads if required and clears any delayed commands.
			} else {
				clearTimeout(this.internal.htmlDlyCmdId);
			}

			// Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime.
			this.htmlElement.media.pause();

			if(!isNaN(time)) {
				try {
					this.htmlElement.media.currentTime = time;
				} catch(err) {
					this.internal.htmlDlyCmdId = setTimeout(function() {
						self.pause(time);
					}, 100);
					return; // Cancel execution and wait for the delayed command.
				}
			}
			if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
				this._html_checkWaitForPlay();
			}
		},
		_html_playHead: function(percent) {
			var self = this;
			this._html_load(); // Loads if required and clears any delayed commands.
			try {
				if((typeof this.htmlElement.media.seekable === "object") && (this.htmlElement.media.seekable.length > 0)) {
					this.htmlElement.media.currentTime = percent * this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1) / 100;
				} else if(this.htmlElement.media.duration > 0 && !isNaN(this.htmlElement.media.duration)) {
					this.htmlElement.media.currentTime = percent * this.htmlElement.media.duration / 100;
				} else {
					throw "e";
				}
			} catch(err) {
				this.internal.htmlDlyCmdId = setTimeout(function() {
					self.playHead(percent);
				}, 100);
				return; // Cancel execution and wait for the delayed command.
			}
			if(!this.status.waitForLoad) {
				this._html_checkWaitForPlay();
			}
		},
		_html_checkWaitForPlay: function() {
			if(this.status.waitForPlay) {
				this.status.waitForPlay = false;
				if(this.css.jq.videoPlay.length) {
					this.css.jq.videoPlay.hide();
				}
				if(this.status.video) {
					this.internal.poster.jq.hide();
					this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
				}
			}
		},
		_html_volume: function(v) {
			if(this.html.audio.available) {
				this.htmlElement.audio.volume = v;
			}
			if(this.html.video.available) {
				this.htmlElement.video.volume = v;
			}
		},
		_html_mute: function(m) {
			if(this.html.audio.available) {
				this.htmlElement.audio.muted = m;
			}
			if(this.html.video.available) {
				this.htmlElement.video.muted = m;
			}
		},
		_flash_setAudio: function(media) {
			var self = this;
			try {
				// Always finds a format due to checks in setMedia()
				$.each(this.formats, function(priority, format) {
					if(self.flash.support[format] && media[format]) {
						switch (format) {
							case "m4a" :
							case "fla" :
								self._getMovie().fl_setAudio_m4a(media[format]);
								break;
							case "mp3" :
								self._getMovie().fl_setAudio_mp3(media[format]);
								break;
						}
						self.status.src = media[format];
						self.status.format[format] = true;
						self.status.formatType = format;
						return false;
					}
				});

				if(this.options.preload === 'auto') {
					this._flash_load();
					this.status.waitForLoad = false;
				}
			} catch(err) { this._flashError(err); }
		},
		_flash_setVideo: function(media) {
			var self = this;
			try {
				// Always finds a format due to checks in setMedia()
				$.each(this.formats, function(priority, format) {
					if(self.flash.support[format] && media[format]) {
						switch (format) {
							case "m4v" :
							case "flv" :
								self._getMovie().fl_setVideo_m4v(media[format]);
								break;
						}
						self.status.src = media[format];
						self.status.format[format] = true;
						self.status.formatType = format;
						return false;
					}
				});

				if(this.options.preload === 'auto') {
					this._flash_load();
					this.status.waitForLoad = false;
				}
			} catch(err) { this._flashError(err); }
		},
		_flash_clearMedia: function() {
			this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE.
			try {
				this._getMovie().fl_clearMedia();
			} catch(err) { this._flashError(err); }
		},
		_flash_load: function() {
			try {
				this._getMovie().fl_load();
			} catch(err) { this._flashError(err); }
			this.status.waitForLoad = false;
		},
		_flash_play: function(time) {
			try {
				this._getMovie().fl_play(time);
			} catch(err) { this._flashError(err); }
			this.status.waitForLoad = false;
			this._flash_checkWaitForPlay();
		},
		_flash_pause: function(time) {
			try {
				this._getMovie().fl_pause(time);
			} catch(err) { this._flashError(err); }
			if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
				this.status.waitForLoad = false;
				this._flash_checkWaitForPlay();
			}
		},
		_flash_playHead: function(p) {
			try {
				this._getMovie().fl_play_head(p);
			} catch(err) { this._flashError(err); }
			if(!this.status.waitForLoad) {
				this._flash_checkWaitForPlay();
			}
		},
		_flash_checkWaitForPlay: function() {
			if(this.status.waitForPlay) {
				this.status.waitForPlay = false;
				if(this.css.jq.videoPlay.length) {
					this.css.jq.videoPlay.hide();
				}
				if(this.status.video) {
					this.internal.poster.jq.hide();
					this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height});
				}
			}
		},
		_flash_volume: function(v) {
			try {
				this._getMovie().fl_volume(v);
			} catch(err) { this._flashError(err); }
		},
		_flash_mute: function(m) {
			try {
				this._getMovie().fl_mute(m);
			} catch(err) { this._flashError(err); }
		},
		_getMovie: function() {
			return document[this.internal.flash.id];
		},
		_checkForFlash: function (version) {
			// Function checkForFlash adapted from FlashReplace by Robert Nyman
			// http://code.google.com/p/flashreplace/
			var flashIsInstalled = false;
			var flash;
			if(window.ActiveXObject){
				try{
					flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + version));
					flashIsInstalled = true;
				}
				catch(e){
					// Throws an error if the version isn't available			
				}
			}
			else if(navigator.plugins && navigator.mimeTypes.length > 0){
				flash = navigator.plugins["Shockwave Flash"];
				if(flash){
					var flashVersion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1");
					if(flashVersion >= version){
						flashIsInstalled = true;
					}
				}
			}
			return flashIsInstalled;
		},
		_validString: function(url) {
			return (url && typeof url === "string"); // Empty strings return false
		},
		_limitValue: function(value, min, max) {
			return (value < min) ? min : ((value > max) ? max : value);
		},
		_urlNotSetError: function(context) {
			this._error( {
				type: $.jPlayer.error.URL_NOT_SET,
				context: context,
				message: $.jPlayer.errorMsg.URL_NOT_SET,
				hint: $.jPlayer.errorHint.URL_NOT_SET
			});
		},
		_flashError: function(error) {
			this._error( {
				type: $.jPlayer.error.FLASH,
				context: this.internal.flash.swf,
				message: $.jPlayer.errorMsg.FLASH + error.message,
				hint: $.jPlayer.errorHint.FLASH
			});
		},
		_error: function(error) {
			this._trigger($.jPlayer.event.error, error);
			if(this.options.errorAlerts) {
				this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context);
			}
		},
		_warning: function(warning) {
			this._trigger($.jPlayer.event.warning, undefined, warning);
			if(this.options.warningAlerts) {
				this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context);
			}
		},
		_alert: function(message) {
			alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message);
		},
		_emulateHtmlBridge: function() {
			var self = this,
			methods = $.jPlayer.emulateMethods;

			// Emulate methods on jPlayer's DOM element.
			$.each( $.jPlayer.emulateMethods.split(/\s+/g), function(i, name) {
				self.internal.domNode[name] = function(arg) {
					self[name](arg);
				};

			});

			// Bubble jPlayer events to its DOM element.
			$.each($.jPlayer.event, function(eventName,eventType) {
				var nativeEvent = true;
				$.each( $.jPlayer.reservedEvent.split(/\s+/g), function(i, name) {
					if(name === eventName) {
						nativeEvent = false;
						return false;
					}
				});
				if(nativeEvent) {
					self.element.bind(eventType + ".jPlayer.jPlayerHtml", function() { // With .jPlayer & .jPlayerHtml namespaces.
						self._emulateHtmlUpdate();
						var domEvent = document.createEvent("Event");
						domEvent.initEvent(eventName, false, true);
						self.internal.domNode.dispatchEvent(domEvent);
					});
				}
				// The error event would require a special case
			});

			// IE9 has a readyState property on all elements. The document should have it, but all (except media) elements inherit it in IE9. This conflicts with Popcorn, which polls the readyState.
		},
		_emulateHtmlUpdate: function() {
			var self = this;

			$.each( $.jPlayer.emulateStatus.split(/\s+/g), function(i, name) {
				self.internal.domNode[name] = self.status[name];
			});
			$.each( $.jPlayer.emulateOptions.split(/\s+/g), function(i, name) {
				self.internal.domNode[name] = self.options[name];
			});
		},
		_destroyHtmlBridge: function() {
			var self = this;

			// Bridge event handlers are also removed by destroy() through .jPlayer namespace.
			this.element.unbind(".jPlayerHtml"); // Remove all event handlers created by the jPlayer bridge. So you can change the emulateHtml option.

			// Remove the methods and properties
			var emulated = $.jPlayer.emulateMethods + " " + $.jPlayer.emulateStatus + " " + $.jPlayer.emulateOptions;
			$.each( emulated.split(/\s+/g), function(i, name) {
				delete self.internal.domNode[name];
			});
		}
	};

	$.jPlayer.error = {
		FLASH: "e_flash",
		NO_SOLUTION: "e_no_solution",
		NO_SUPPORT: "e_no_support",
		URL: "e_url",
		URL_NOT_SET: "e_url_not_set",
		VERSION: "e_version"
	};

	$.jPlayer.errorMsg = {
		FLASH: "jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ", // Used in: _flashError()
		NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.", // Used in: _init()
		NO_SUPPORT: "It is not possible to play any media format provided in setMedia() on this browser using your current options.", // Used in: setMedia()
		URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() and _addHtmlEventListeners()
		URL_NOT_SET: "Attempt to issue media playback commands, while no media url is set.", // Used in: load(), play(), pause(), stop() and playHead()
		VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplayer.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used in: jPlayerReady()
	};

	$.jPlayer.errorHint = {
		FLASH: "Check your swfPath option and that Jplayer.swf is there.",
		NO_SOLUTION: "Review the jPlayer options: support and supplied.",
		NO_SUPPORT: "Video or audio formats defined in the supplied option are missing.",
		URL: "Check media URL is valid.",
		URL_NOT_SET: "Use setMedia() to set the media URL.",
		VERSION: "Update jPlayer files."
	};

	$.jPlayer.warning = {
		CSS_SELECTOR_COUNT: "e_css_selector_count",
		CSS_SELECTOR_METHOD: "e_css_selector_method",
		CSS_SELECTOR_STRING: "e_css_selector_string",
		OPTION_KEY: "e_option_key"
	};

	$.jPlayer.warningMsg = {
		CSS_SELECTOR_COUNT: "The number of css selectors found did not equal one: ",
		CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",
		CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",
		OPTION_KEY: "The option requested in jPlayer('option') is undefined."
	};

	$.jPlayer.warningHint = {
		CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.",
		CSS_SELECTOR_METHOD: "Check your method name.",
		CSS_SELECTOR_STRING: "Check your css selector is a string.",
		OPTION_KEY: "Check your option name."
	};
})(jQuery);
;
/* Modernizr custom build of 1.7pre: csstransforms */
window.Modernizr=function(a,b,c){function G(){}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return!!E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c&&(!b||b(a[d],j)))return!0}function D(a,b){return(""+a).indexOf(b)!==-1}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="1.7pre",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v,w=function(a){var c=b.createElement("style"),d=b.createElement("div"),e;c.textContent=a+"{#modernizr{height:3px}}",h.appendChild(c),d.id="modernizr",g.appendChild(d),e=d.offsetHeight===3,c.parentNode.removeChild(c),d.parentNode.removeChild(d);return!!e},x=function(){function d(d,e){e=e||b.createElement(a[d]||"div");var f=(d="on"+d)in e;f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=C(e[d],"function"),C(e[d],c)||(e[d]=c),e.removeAttribute(d))),e=null;return f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),y=({}).hasOwnProperty,z;C(y,c)||C(y.call,c)?z=function(a,b){return b in a&&C(a.constructor.prototype[b],c)}:z=function(a,b){return y.call(a,b)},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])};for(var H in r)z(r,H)&&(v=H.toLowerCase(),e[v]=r[H](),u.push((e[v]?"":"no-")+v));e.input||G(),e.crosswindowmessaging=e.postmessage,e.historymanagement=e.history,e.addTest=function(a,b){a=a.toLowerCase();if(!e[a]){b=!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b;return e}},A(""),j=l=null,e._enableHTML5=f,e._version=d,g.className=g.className.replace(/\bno-js\b/,"")+" js "+u.join(" ");return e}(this,this.document);
/*
 * CirclePlayer for the jPlayer Plugin (jQuery)
 * http://www.jplayer.org
 *
 * Copyright (c) 2009 - 2011 Happyworm Ltd
 * Dual licensed under the MIT and GPL licenses.
 *  - http://www.opensource.org/licenses/mit-license.php
 *  - http://www.gnu.org/copyleft/gpl.html
 *
 * Version: 1.0.1 (jPlayer 2.0.9)
 * Date: 30th May 2011
 *
 * Author: Mark J Panaghiston @thepag
 *
 * CirclePlayer prototype developed by:
 * Mark Boas @maboa
 * Silvia Benvenuti @aulentina
 * Jussi Kalliokoski @quinirill
 *
 * Inspired by :
 * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt
 * and
 * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause
 *
 * Standing on the shoulders of :
 * John Resig @jresig
 * Mark Panaghiston @thepag
 * Louis-Rémi Babé @Louis_Remi
 */
jQuery.noConflict();
var CirclePlayer = function(jPlayerSelector, media, options) {
	var	self = this,

		defaults = {
			// solution: "flash, html", // For testing Flash with CSS3
			supplied: "m4a, oga",
			// Android 2.3 corrupts media element if preload:"none" is used.
			// preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too.
			cssSelectorAncestor: "#cp_container_1",
			cssSelector: {
				play: ".cp-play",
				pause: ".cp-pause"
			}
		},

		cssSelector = {
			bufferHolder: ".cp-buffer-holder",
			buffer1: ".cp-buffer-1",
			buffer2: ".cp-buffer-2",
			progressHolder: ".cp-progress-holder",
			progress1: ".cp-progress-1",
			progress2: ".cp-progress-2",
			circleControl: ".cp-circle-control"
		};

	this.cssClass = {
		gt50: "cp-gt50",
		fallback: "cp-fallback"
	};

	this.spritePitch = 104;
	this.spriteRatio = 0.24; // Number of steps / 100

	this.player = jQuery(jPlayerSelector);
	this.media = jQuery.extend({}, media);
	this.options = jQuery.extend(true, {}, defaults, options); // Deep copy

	this.cssTransforms = Modernizr.csstransforms;
	this.audio = {};
	this.dragging = false; // Indicates if the progressbar is being 'dragged'.

	this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy.

	this.jq = {};
	jQuery.each(cssSelector, function(entity, cssSel) {
		self.jq[entity] = jQuery(self.options.cssSelectorAncestor + " " + cssSel);
	});

	this._initSolution();
	this._initPlayer();
};

CirclePlayer.prototype = {
	_createHtml: function() {
	},
	_initPlayer: function() {
		var self = this;
		this.player.jPlayer(this.options);

		this.player.bind(jQuery.jPlayer.event.ready + this.eventNamespace, function(event) {
			if(event.jPlayer.html.used && event.jPlayer.html.audio.available) {
				self.audio = jQuery(this).data("jPlayer").htmlElement.audio;
			}
			jQuery(this).jPlayer("setMedia", self.media);
			self._initCircleControl();
		});

		this.player.bind(jQuery.jPlayer.event.play + this.eventNamespace, function(event) {
			jQuery(this).jPlayer("pauseOthers");
		});

		// This event fired as play time increments
		this.player.bind(jQuery.jPlayer.event.timeupdate + this.eventNamespace, function(event) {
			if (!self.dragging) {
				self._timeupdate(event.jPlayer.status.currentPercentAbsolute);
			}
		});

		// This event fired as buffered time increments
		this.player.bind(jQuery.jPlayer.event.progress + this.eventNamespace, function(event) {
			var percent = 0;
			if((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) {
				if(self.audio.duration > 0) {
					var bufferTime = 0;
					for(var i = 0; i < self.audio.buffered.length; i++) {
						bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i);
						// console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration);
					}
					percent = 100 * bufferTime / self.audio.duration;
				} // else the Metadata has not been read yet.
				// console.log("percent = " + percent);
			} else { // Fallback if buffered not supported
				// percent = event.jPlayer.status.seekPercent;
				percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined.
			}
			self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill.
			// Firefox 4 does not always give the final progress event when buffered = 100%
		});

		this.player.bind(jQuery.jPlayer.event.ended + this.eventNamespace, function(event) {
			self._resetSolution();
		});
	},
	_initSolution: function() {
		if (this.cssTransforms) {
			this.jq.progressHolder.show();
			this.jq.bufferHolder.show();
		}
		else {
			this.jq.progressHolder.addClass(this.cssClass.gt50).show();
			this.jq.progress1.addClass(this.cssClass.fallback);
			this.jq.progress2.hide();
			this.jq.bufferHolder.hide();
		}
		this._resetSolution();
	},
	_resetSolution: function() {
		if (this.cssTransforms) {
			this.jq.progressHolder.removeClass(this.cssClass.gt50);
			this.jq.progress1.css({'transform': 'rotate(0deg)'});
			this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide();
		}
		else {
			this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px');
		}
	},
	_initCircleControl: function() {
		var self = this;
		this.jq.circleControl.grab({
			onstart: function(){
				self.dragging = true;
			}, onmove: function(event){
				var pc = self._getArcPercent(event.position.x, event.position.y);
				self.player.jPlayer("playHead", pc).jPlayer("play");
				self._timeupdate(pc);
			}, onfinish: function(event){
				self.dragging = false;
				var pc = self._getArcPercent(event.position.x, event.position.y);
				self.player.jPlayer("playHead", pc).jPlayer("play");
			}
		});
	},
	_timeupdate: function(percent) {
		var degs = percent * 3.6+"deg";

		var spriteOffset = (Math.floor((Math.round(percent))*this.spriteRatio)-1)*-this.spritePitch;

		if (percent <= 50) {
			if (this.cssTransforms) {
				this.jq.progressHolder.removeClass(this.cssClass.gt50);
				this.jq.progress1.css({'transform': 'rotate(' + degs + ')'});
				this.jq.progress2.hide();
			} else { // fall back
				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
			}
		} else if (percent <= 100) {
			if (this.cssTransforms) {
				this.jq.progressHolder.addClass(this.cssClass.gt50);
				this.jq.progress1.css({'transform': 'rotate(180deg)'});
				this.jq.progress2.css({'transform': 'rotate(' + degs + ')'});
				this.jq.progress2.show();
			} else { // fall back
				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
			}
		}
	},
	_progress: function(percent) {
		var degs = percent * 3.6+"deg";

		if (this.cssTransforms) {
			if (percent <= 50) {
				this.jq.bufferHolder.removeClass(this.cssClass.gt50);
				this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'});
				this.jq.buffer2.hide();
			} else if (percent <= 100) {
				this.jq.bufferHolder.addClass(this.cssClass.gt50);
				this.jq.buffer1.css({'transform': 'rotate(180deg)'});
				this.jq.buffer2.show();
				this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'});
			}
		}
	},
	_getArcPercent: function(pageX, pageY) {
		var	offset	= this.jq.circleControl.offset(),
			x	= pageX - offset.left - this.jq.circleControl.width()/2,
			y	= pageY - offset.top - this.jq.circleControl.height()/2,
			theta	= Math.atan2(y,x);

		if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) {
			theta = 2 * Math.PI + theta;
		}

		// theta is now value between -0.5PI and 1.5PI
		// ready to be normalized and applied

		return (theta + Math.PI / 2) / 2 * Math.PI * 10;
	},
	setMedia: function(media) {
		this.media = $.extend({}, media);
		this.player.jPlayer("setMedia", this.media);
	},
	play: function(time) {
		this.player.jPlayer("play", time);
	},
	pause: function(time) {
		this.player.jPlayer("pause", time);
	},
	destroy: function() {
		this.player.unbind(this.eventNamespace);
		this.player.jPlayer("destroy");
	}
};
;
(function ($) {
	Drupal.behaviors.wire = {
		attach: function(context, settings) {
		// CONTEXT FUNCTIONS BEGIN =====================
		    
			var loader1 = '<div id="ajx-loader"><img src="/sites/all/themes/wire/img/loader_small.gif" /></div>'; // Animated loading gif
			var loader2 = '<div id="ajx-loader"><img src="/sites/all/themes/wire/img/loader.gif" />&nbsp;Please wait, loading…</div>'; // Animated loading gif
			var loader3 = '<div id="ajx-loader"><img src="/sites/all/themes/wire/img/loader.gif" />&nbsp;Please wait, processing order…</div>'; // Animated loading gif
			var loader4 = '<div id="ajx-loader"><img src="/sites/all/themes/wire/img/loader_small.gif" />&nbsp;Please wait, adding item...</div>'; // Animated loading gif
			var loader5 = '<div id="ajx-loader"><img src="/sites/all/themes/wire/img/loader_small.gif" />&nbsp;processing…</div>'; // Animated loading gif
			var loader6 = '<img src="/sites/all/themes/wire/img/loader_small.gif" />';
			var loader7 = '<div id="ajx-loader"><img src="/sites/all/themes/wire/img/loader_small.gif" />&nbsp;getting rate plans…</div>'; // Animated loading gif
			
			// My account overview tabs.
			$("#my-account-tabs").tabs();
			
			// On - Off switch for call detatils
			$("#filter-btns").buttonset();
			
			// Y/N for profile update
			$("#optin-btns").buttonset();
			
			// Y/N for daily sms balance
			$("#dailysms-btns").buttonset();
			
			// Auto payment buttonset
			$("#autopay-billing-btns").buttonset();
			
			$("#filter-btns label.ui-button").click(function(){
				var id = $('#tab-btn-3').attr('rel');
				$("#call-details-select option:selected").each(function () {
					var filter = $('#filter-btns label.ui-state-active').text();
					var date = $(this).val();
					$('#ajx-status').html(loader2);
  					$.ajax({
						url: '/my-account/call-details/?id='+id+'&date='+date+'&filter='+filter,
						success: function(data){
							var div = $('#details-table', $(data)).addClass('done');
    						$('#call-trans-details').html(div);
							$('#ajx-status').html('&nbsp;');
						}
					});
  				});
			});
			
			// Set Daily Balance SMS
			$("#dailysms-btns label.ui-button").click(function(){
				var mdn = $('#dailysms-btns').attr('title');
				var setvalue = $('#dailysms-btns label.ui-state-active').text();
				if(setvalue == "on") {
					setvalue = "Y";
				} else {
					setvalue = "N";
				}
				$('#dailybalancesms-status').html(loader5);
				$.ajax({
					url: '/my-account/dailybalancesms',
					type: 'POST',
					data: 'mdn='+mdn+'&setvalue='+setvalue,
					success: function(data){
						var res = $('#ajx-response', $(data)).addClass('done');
						$('#dailybalancesms-status').html(res);
						$('#dailysms-btns').fadeOut(500);
						$('#dailybalancesms-status').fadeOut(10000)
					}
				});
			});
			
			// Set Daily Balance SMS
			$("#autopay-billing-btns label.ui-button").click(function(){
				var billing_type = $('#autopay-billing-btns label.ui-state-active').text();
				switch(billing_type)
				{
					case 'monthly':
						$('#none-info').hide();
						$('#balance-info').hide();
						$('#monthly-info').fadeIn(500);
						$('#everymonth-info').hide();
  						break;
  					case 'every month':
						$('#none-info').hide();
						$('#balance-info').hide();
						$('#monthly-info').hide();
						$('#everymonth-info').fadeIn(500);
  						break;
  					case 'low balance':
  						$('#none-info').hide();
  						$('#monthly-info').hide();
  						$('#balance-info').fadeIn(500);
  						$('#everymonth-info').hide();
  						break;
  					case 'no payment':
  						$('#balance-info').hide();
						$('#monthly-info').hide();
  						$('#none-info').fadeIn(500);
  						$('#everymonth-info').hide();
  						break;
				}
			});
			
			// Auto Pay Button
			$('#autopay-btn').click(function(){
				$('#autopay').toggle('slow', function() {
    				var billing_option = $('#autopay-billing-btns label.ui-state-active').text();
					switch(billing_option)
					{
						case 'monthly':
							$('#none-info').hide();
							$('#balance-info').hide();
							$('#monthly-info').fadeIn(500);
							$('#everymonth-info').hide();
  							break;
	  					case 'every month':
							$('#none-info').hide();
							$('#balance-info').hide();
							$('#monthly-info').hide();
							$('#everymonth-info').fadeIn(500);
	  						break;
	  					case 'low balance':
	  						$('#none-info').hide();
	  						$('#monthly-info').hide();
	  						$('#balance-info').fadeIn(500);
	  						$('#everymonth-info').hide();
	  						break;
	  					case 'no payment':
	  						$('#balance-info').hide();
							$('#monthly-info').hide();
	  						$('#none-info').fadeIn(500);
	  						$('#everymonth-info').hide();
	  						break;
					}
  				});
  				return false;
			});
			
			$('#set-autopay-btn').click(function(){
				var url = $(this).attr('rel');
				var id = $('#autopay').attr('role');
				var billing_type = $('#autopay-billing-btns label.ui-state-active').text();
				switch(billing_type)
				{
					case 'monthly':
						billing_type = "PL";
  						break;
  					case 'every month':
						billing_type = "OM";
  						break;
  					case 'low balance':
  						billing_type = "BT";
  						break;
  					case 'no payment':
  						billing_type = "NONE";
  						break;
				}
				
				var billing_amount = '';
				var billing_day = '';
				$("#autopayment-amount-select option:selected").each(function () {
					billing_amount = $(this).val();
				});
				$('#autopay-msg').fadeIn(500);
				$('#balance-info').hide();
				$('#monthly-info').hide();
  				$('#none-info').hide();
  				$('#everymonth-info').hide();
				$('#autopay-msg').html(loader2);
				$.ajax({
						url: url+'?id='+id,
						type: 'POST',
						data: 'type='+billing_type+'&amount='+billing_amount+'&day'+billing_day,
						success: function(data){
							var div = $('#ajx-response', $(data)).addClass('done');
  							$('#autopay-msg').fadeIn(500);
    						$('#autopay-msg').html(div);
						}
				});
				return false;
			});
			
			// Month select for call details
			$('#call-details-select').change(function() {
				var id = $('#tab-btn-3').attr('rel');
				$("#call-details-select option:selected").each(function () {
					var filter = $('#filter-btns label.ui-state-active').text();
					var date = $(this).val();
					$('#ajx-status').html(loader2);
  					$.ajax({
						url: '/my-account/call-details/?id='+id+'&date='+date+'&filter='+filter,
						success: function(data){
							var div = $('#details-table', $(data)).addClass('done');
    						$('#call-trans-details').html(div);
							$('#ajx-status').html('&nbsp;');
						}
					});
  				});
			});
			
			
			// My Account call and trans details tab.
			$('#tab-btn-3').click(function() {
				// Get current service id
				var id = $(this).attr('rel');
				
				// Start loader
				$('#ajx-status').html(loader2);
				
				$.ajax({
					url:	'/my-account/call-details/?id='+id,
					success: function(data){
						var div = $('#details-table', $(data)).addClass('done');
    					$('#call-trans-details').html(div);
						$('#ajx-status').html('&nbsp;');
					}
				});
			});
			
			// My Account Loyalty Numbers
			$('#tab-btn-2').click(function() {
				// Get current service id
				var id = $('#loyalty-numbers').attr('role');
				$('#loyalty-numbers-frm').html(loader2);
				$.ajax({
					url:'/my-account/loyalty-numbers/?id='+id,
					success: function(data){
						var ajx_res = $('#ajx-res', $(data));
    					$('#loyalty-numbers-frm').html(ajx_res);
    					// Add Loyalty Number
						$('#loyalty-number-add-btn').click(function(){
							var url = $(this).attr('rel');
							var loyalty_number = $('#loyalty-number-field').val();
							loyalty_number = loyalty_number.replace(/\D/g,'');
							$('#loyalty-numbers-frm').html(loader2);
							$.ajax({
								url: url+'?id='+id,
								type: 'POST',
								data: 'number='+loyalty_number,
								success: function(data){
									var ajx_res = $('#ajx-res', $(data));
									$("#loyalty-numbers-frm").html(ajx_res);
								}
							});
						});
						$('.loyalty-numbers-remove').click(function(){
							var url = $(this).attr('rel');
							$('#loyalty-numbers-frm').html(loader2);
							$.ajax({
								url: url,
								type: 'GET',
								success: function(data){
									var ajx_res = $('#ajx-res', $(data));
									$("#loyalty-numbers-frm").html(ajx_res);
								}
							})
						});
					}
				});
			});
			
			
    		// Downloads Coming Soon
    		$('.downloads-link').attr('href','#');
    		$('.downloads-link').click(function(){
    			var title = "Ringtones and Wallpapers";
    			var url = $(this).attr('rel');
				$("#dialog").dialog({height:120,width:300,modal:true,title:title,resizable:false});
				$("#dialog").html("<div class='inner'>Ringtones and Wallpapers coming soon</div>");
    		});
    		
    		
    		// Activation Coming Soon	
    		$('#activate-btn').attr('href','#');
    		$('#activate-btn').click(function(){
    			var title = "Activation Coming Soon";
    			var url = $(this).attr('rel');
				$("#dialog").dialog({height:200,width:350,modal:true,title:title,resizable:false});
				$("#dialog").html("<div class='inner'><p>Online Activation Coming Soon.</p><p>To activate your i-wireless phone from your handset insert and charge your phone's battery, and follow the activation instructions included with your phone.</p><p>For assistance completing the activation process, call 611 from your i-wireless phone.</p></div>");
    		});
    		
    		
    		// Login info button
    		$('.login-info-btn').click(function(){
    			var formid = $(this).attr('id');
    			var status = "";
    			if(formid == 'login-info-frm1-btn') {
    				status = $('#login-status-frm1');
    				info = $('#info-frm1');
    			} else {
    				status = $('#login-status');
    				info = $('#info');
    			}
    			
    			status.html('<div id="msg">Enter your phone number and passcode to login. <a href="#" class="forgot-pass-link" rel="/my-account/forgot-pass">Click here</a> if you forgot your passcode.</div>');
				status.fadeIn(500);
				status.delay(5000).fadeOut(500);
    			return false;
    		});
    		
    		// Forgot Passcode
    			$('.forgot-pass-link').click(function(){
    				var url = $(this).attr('rel');
    				var title = "Forgot Passcode";
    				var status = $("#status-msg");
    				$("#dialog").html(loader2);
					$("#dialog").dialog({height:200,width:400,modal:true,title:title,resizable:false});
					$.ajax({
						url:url,
						success: function(data){
							var ajx_res = $('#ajx-res', $(data));
    						$('#dialog').html(ajx_res);
    						$('#forgot-pass-go').click(function(){
    							var userid = $('#forgot-pass-userid').val();
    							var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    							var	isemail = emailReg.test(userid);
    							if(isemail == false){
    								userid = userid.replace(/\D/g,'');
    							}	
    							url = $(this).attr('rel');
    							$(this).removeClass('green');
    							$(this).html(loader2);
    							$.ajax({
    								url:url,
    								type:'POST',
    								data:'userid='+userid,
    								success: function(data){
    									var ajx_res = $('#ajx-res', $(data));
										status.html(ajx_res);
										status.fadeIn(500);
										status.delay(5000).fadeOut(500);
										$("#dialog").dialog('close');
    								}
    							});
    						});
						}
					})
					return false;
    			});
    		
    		//Login 
    		$('.login-frm-btn').click(function() {
    			var formid = $(this).attr('id');
				login(formid);
    		});
    		
    		$('#login-form input').bind('keypress', function(e) {
        		if(e.keyCode==13){
              		var formid = $(this).attr('id');
					login(formid);
        		}
			});
    		
    		function callback() {
				setTimeout(function() {
					$('#login-status').addAttr('style').hide().fadeOut();
				}, 500 );
			};
    		
    		var clearMePrevious = '';
    		
    		// clear input on focus
			$('.form-text').focus(function(){
				if($(this).val()==$(this).attr('title')){
					clearMePrevious = $(this).val();
					$(this).val('');
				}
			});

			// if field is empty afterward, add text again
			$('.form-text').blur(function(){
				if($(this).val()==''){
					$(this).val($(this).attr('title'));
				}
			});
    		
    		
    		// My account change MDN
    		$('#my-accounts-mdns').change(function() {
    			$("#my-accounts-mdns option:selected").each(function () {
  					window.location='/my-account/overview/?id='+$(this).val();
  				});
			});
			
			$('#topup-myaccount-select').change(function(){
				var mdn = $(this).attr('name');
				var amount = $(this).val();
				$("#addairtime-status").html(loader5);
				$.ajax({
					url: '/my-cart/?action=topup',
					type: 'POST',
						data: 'mdn='+mdn+'&amount='+amount,
						success: function(data){
							window.location='/my-cart/';
					}
				});
			});
			
			// Webpacket my account select menu
			$('#webpacks-myaccount-select').change(function(){
				var mdn = $(this).attr('name');
				var webpacket = $(this).val();
				var price = '';
				$("#webpacks-myaccount-select option:selected").each(function () {
					price = $(this).attr('title');
				});
				var title = 'Webpacket Confirmation';
				$( "#dialog" ).html('<p>Are you sure you want to deduct $'+price+'.00 from your account balance?</p>');
				$( "#dialog" ).dialog({
					resizable: false,
					height:140,
					modal: true,
					buttons: {
						OK: function() {
							 $(this).dialog('destroy');
							$("#webpacket-status").html(loader5);
							$.ajax({
								url: '/my-account/webpackets',
								type: 'POST',
									data: 'mdn='+mdn+'&charegeid='+webpacket,
									success: function(data){
									var ajx_res = $('#ajx-response', $(data)).addClass('done');
									var new_balance =  $('#new-data-amount', $(data));
									$('#webpacket-status').html(ajx_res);
									$('#webpacks-myaccount').fadeOut(500);
									$('#webpacket-status').fadeOut(10000);
									if(ajx_res.attr('role')=='3606'){
										$('#topup-myaccount').fadeIn('slow', function() {
    										// Animation complete.
  										});
									}
								}
							});
						},
						Cancel: function() {
							 $(this).dialog('destroy');
						}
					}
				});
			});
			
			// Adding airtime from within the myaccount.
			$('#add-airtime-btn').click(function(){
				$('#topup-myaccount').toggle('slow', function() {
    				// Animation complete.
  				});
  				return false;
			});
			
			// Set daily sms buttons.
			$('#set-dailysms-btn').click(function(){
				$('#dailysms-btns').toggle('slow', function() {
    				// Animation complete.
  				});
  				return false;
			});
			
			// Adding webpacks from within the myaccount.
			$('#add-webpacks-btn').click(function(){
				$('#webpacks-myaccount').toggle('slow', function() {
    				// Animation complete.
  				});
  				return false;
			});
			
			// My account dialog links
			$('.my-acct-dialog').click(function(){
				var title = this.title;
				var w = $(this).attr("w");
				var h = $(this).attr("h");
				$("#dialog").dialog({height:h,width:w,modal:true,title:title,resizable:false}); // Open jQuery UI dialog 
				$("#dialog").html(loader2);
				
				$.ajax({
  					url: $(this).attr('rel'),
  					success: function(data){
  						var div = $('#ajx-response', $(data)).addClass('done');
    					$('#dialog').html(div);
    					
    					// Print Order
						$('#printorder-btn').click(function(){
    						var w = window.open('blank.html', 'order', 'height=400,width=600');
		        				w.document.write('<html><head><title>ORDER: '+$(this).attr('rel')+'</title>');
		       				 	w.document.write('<link rel="stylesheet" href="sites/all/themes/wire/css/print.css" type="text/css" />');
		        				w.document.write('</head><body >');
		        				w.document.write($('.scrollbox').html());
		        				w.document.write('</body></html>');
		        				w.document.close();
		        				w.print();
		        			return true;
    					});
    					// Begin Change Passcode --------------------------------------------------------
						$('#change-passcode-btn').click(function(){
							var new_pcde = $("#new_pcde").val();
							$("#change-passcode").html(loader2);
							$.ajax({
								url: '/my-account/change-passcode',
								type: 'POST',
	  							data: 'new_pcde='+new_pcde,
								success: function(data){
									var div = $('#ajx-response-2', $(data)).addClass('done');
									$("#change-passcode").html(div);
								}
							});
						}); // End Change Passcode ------------------------------------------------------
  					}	
				});
			});
			
			
			// Change Plan
			$('#change-plan-btn').click(function(){
				var planid = $('input:radio[name=plan]:checked').val();
				var ondate = $('input:radio[name=ondate]:checked').val();
				var serviceid = $('input:hidden[name=service]').val();
				$("#change-status").html(loader2);
				$.ajax({
					url: '/my-account/change-plan/?id='+serviceid,
					type: 'POST',
					data: 'planid='+planid+'&ondate='+ondate,
					success: function(data){
						var ajx_res = $('#ajx-res', $(data)).addClass('done');
						$("#change-status").html(ajx_res);
					}
				});
			});
			
			
			// Remove shopping cart item
			$('.cart-remove-btn').click(function(){
				var itemrow = '#'+$(this).closest("tr").attr("id");
				var itemrowamount = '#'+$(this).closest("tr").attr("id")+' td.amount';
				$(itemrowamount).html(loader1);
				$.ajax({
					url: $(this).attr('rel'),
					success: function(data){
						var msg = $('#alert-msg', $(data));
						var count = $('#count-msg', $(data));
						var subtotal = $('td.subtotal', $(data));
						var total = $('td.total', $(data));
						var cart_tbl = $("#cart-tbl", $(data));
						var zipconfirm = $("#zipconfirm-hidden", $(data));
						var count = cart_tbl.attr('rel');
						if(msg.text() == 'success') {
							$(itemrow).fadeOut(500);
							$('td.subtotal').text(subtotal.text());
							$('td.total').text(total.text());
							$('#cart-count').text(count);
							$('#zipconfirm-hidden').val(zipconfirm.val());
						}
					}
				});
				return false;
			});
			
			// Add Item to Cart
			$('.add-cart').click(function(){
				var productid = $(this).attr('rel');
				$(this).attr('style', 'text-decoration:none;');
				$(this).attr('onclick', 'return false;');
				$(this).removeClass('green');
				$(this).html(loader4);
				$.ajax({
					url: '/my-cart/',
					type: 'POST',
					data: 'productid='+productid,
					success: function(data){
						window.location = '/my-cart/';
						
					}
				});
				return false;
			});
			
			// Mobile Hotspot
			$('#hotspots-btn').click(function(){
				var title = 'ACTIVATE MOBILE HOTSPOT';
				var mdn = $('#mdn-field').val().replace(/\D/g,'');
				var chargeid = "MBLHOTSPOT";
				var html = '<table class="details hotspot"><tr><td>';
					html = html + '<p>Now you can connect up to five (5) Wi-Fi enabled devices to the Internet using your i-wireless Android smartphone for just $10/month.</p>';
					html = html +  '<p>Use i-wireless Mobile HotSpot with:</p>';
					html = html +  '<ul><li>Laptops</li><li>Tablets</li><li>MP3 players</li><li>Digital cameras</li></li><li>PDAs</li><li>Portable gaming systems</li><li>And more</li></ul>';
					html = html + '</td><td>';
					html = html +  '<p><strong>HOW IT WORKS</strong></p>';
					html = html +  '<p>Access your i-wireless Mobile Hotspot using the data allowance included in your monthly cell phone rate plan or by adding more data with a Mobile Web Pack.';
					html = html +  '<br />*i-wireless Mobile HotSpot is available on the following devices:</p>';
					html = html +  '<ul><li>Optimus</li><li>Replenish</li><li>Milano</li></ul>';
					html = html +  '<p>(Mobile HotSpot is not available on the HTC Hero or the Sanyo Zio)</p>';
					html = html +  '</td></tr></table>';
					
				var confirm_msg = '<div style="float:left;width:435px;font-weight:bold;">';
					confirm_msg = confirm_msg + 'By clicking activate your account balance will be charged $10 and will enable a mobile hotspot for the number ';
					confirm_msg = confirm_msg + '['+mdn+'].';
					confirm_msg = confirm_msg + '</div>';
					
				$( "#dialog" ).html(html);
				$( "#dialog" ).dialog({
					resizable: false,
					modal: true,
					height:400,
					width:600,
					title: title,
					buttons: {
						Activate: function() {
							//$("#webpacket-status").html(loader5);
							$.ajax({
								url: '/iwireless/api/hotspot.php',
								dataType: 'xml',
								type: 'POST',
								data: 'mdn='+mdn+'&chargeid='+chargeid,
								success: function(xml){
									var result_code = $(xml).find('ResultCode').text();
									var problem_desc = $(xml).find('ProblemDesc').text();
									if(result_code =='0'){
										$('#webpacket-status').html('Success. You can now use your mobile device at a hotspot!');
									}else{
										$('#webpacket-status').html(problem_desc);
									}
									$('#dialog').dialog('destroy');
									$('#webpacks-myaccount').fadeOut(500);
									$('#webpacket-status').fadeOut(15000);
								}
							});
						},
						Cancel: function() {
							 $(this).dialog('destroy');
						}
					}
				});
				$('.ui-dialog-buttonpane').append(confirm_msg);
				$('.ui-dialog-buttonpane').attr('style','padding:12px;')
			});
			
			// Add Airtim
			$('.addairtime-btn').click(function(){
				var url = $(this).attr('rel');
				var title = "Add Airtime";
				var status = $("#status-msg");
				$("#dialog").dialog({height:500,width:700,modal:true,title:title,resizable:false});
				$("#dialog").html(loader2);
				$.ajax({
					url: url,
					type: 'GET',
					success: function(data){
						var div = $('#ajx-response', $(data)).addClass('done');
						$("#dialog").html(div);
						$('#redeem-airtime-btn').click(function(){
							url = $(this).attr('rel');
							var phone_num = $('#redeem-airtime-phone').val();
								phone_num = phone_num.replace(/\D/g,'');
							var pin_num = $('#redeem-airtime-pin').val();
							if(phone_num != '' && pin_num != '') {
							$(this).removeClass('green');
							$(this).html(loader2);
								$.ajax({
									url: url,
									type: 'POST',
									data: 'phone_num='+phone_num+'&pin_num='+pin_num,
									success: function(data){
										var div = $('#ajx-response', $(data)).addClass('done');
										status.html(div);
										status.fadeIn(500);
										status.delay(5000).fadeOut(500);
										$('#dialog').dialog('destroy');
									}
								});
							} else {
								$('#redeem-airtime-phone').addClass('error');
								$('#redeem-airtime-pin').addClass('error');
							}
						});
					}
				});
			});
			
			// Update cart when user changes quantity
			$("#cart-tbl input[type='text']").change( function() {
				var isstr = isNaN($(this).val());
				var productid = $(this).attr('role');
				var quantity = $(this).val();
				if(isstr) {
					$(this).val('1');
					alert('Please make sure you only use numeric values.');
				}
				var itemrow = '#'+$(this).closest("tr").attr("id");
				var itemrowamount = '#'+$(this).closest("tr").attr("id")+' td.amount';
				$(itemrowamount).html(loader1);
				$.ajax({
					url: '/my-cart/?action=update', //$(this).attr('role')+$(this).val(),
					type:'POST',
					data: 'productid='+productid+'&quantity='+quantity,
					success: function(data){
						var msg = $('#alert-msg', $(data));
						var amount = $(itemrowamount, $(data));
						var subtotal = $('td.subtotal', $(data));
						var total = $('td.total', $(data));
						var cart_tbl = $("#cart-tbl", $(data));
						var count = cart_tbl.attr('rel');
						if(msg.text() == 'success') {
							$(itemrowamount).html(amount.text());
							$('td.subtotal').text(subtotal.text());
							$('td.total').text(total.text());
							$('#cart-count').text(count);
						}
					}
				});
			});
			
			// Check zip coverage button
			$('#zipcode-coverage-btn').click(function(){
				var zipcode = $('input:text[name=zipcode]').val();
				var zipreg = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
				var iszipcode =  zipreg.test(zipcode);
				if(iszipcode){
					$("#zip-msg").removeClass('error');
					$("#zip-msg").html(loader1);
					if(zipcode != ''){
						$.ajax({
							url: $(this).attr('rel')+zipcode,
							success: function(data){
								$("#zip-msg").hide();
								var msg = $('#zip-msg', $(data));
								var confirm = $('input:hidden[name=zipconfirm]', $(data));
								if(confirm.val() == "1"){
									 $('input:hidden[name=zipconfirm]').val('1')
								}
								$('#zip-msg').html(msg.text());
								$("#zip-msg").fadeIn(500);
							}
						});
					}else{
						$("#zip-msg").hide();
						$("#zip-msg").addClass('error');
						$("#zip-msg").html('Please specify a valid postal/zip code');
						$("#zip-msg").fadeIn(500);
					}
				} else {
					$("#zip-msg").hide();
					$("#zip-msg").addClass('error');
					$("#zip-msg").html('Please specify a valid postal/zip code');
					$("#zip-msg").fadeIn(500);
				}
			});
			
			// Checkout
			$('#checkout-btn').click(function(){
				var confirm = $('input:hidden[name=zipconfirm]').val();
				if(confirm == "1"){
					window.location = $(this).attr('rel');
				} else {
					$("#zip-msg").hide();
					$("#zip-msg").addClass('error');
					$("#zip-msg").html('Please specify a valid postal/zip code');
					$("#zip-msg").fadeIn(500);
				}
			});
			
			$('#cart-profile-checkout').click(function(){
				var url = $(this).attr('rel');
				var error = false;
				var alertmsg = 'Please add a valid credit card  and billing information to your account before proceeding.';
				var billfirstname = $('input:text[name=billfirstname]').val();
				if (billfirstname == ''){
					error = true;
				}
				var billlastname = $('input:text[name=billlastname]').val();
				if (billlastname == ''){
					error = true;
				}
				var billaddress = $('input:text[name=billaddress]').val();
				if (billaddress == ''){
					error = true;
				}
				var billcity = $('input:text[name=billcity]').val();
				if (billcity == ''){
					error = true;
				}
				var billstate = $('select.billstate option:selected').val();
				if (billstate == ''){
					error = true;
				}
				var billzip = $('input:text[name=billzip]').val();
				if (billzip == ''){
					error = true;
				}
				
				if(url == 'no-cc' ){
				 	error = true;
				}  
				
				if(error){
					alert(alertmsg);
				}else{
					window.location = url;
				}
				return false;
			});
			
			// Add Airtime To Cart
			$('#topup-amount-select').change(function() {
				var amount = '';
				var mdn = '';
				$("#topup-amount-select option:selected").each(function () {
					amount = $(this).val();
  				});
  				$("#service-number-select option:selected").each(function () {
					mdn = $(this).val();
  				});
  				$('#addairtime-status-msg').html(loader4);
				$.ajax({
					url: '/my-cart/?action=topup',
					type: 'POST',
					data: 'mdn='+mdn+'&amount='+amount,
					success: function(data){
						var msg = $('#alert-msg', $(data));
						if(msg.text() == 'success') {
							location.reload(true);
						}
					}
				});
			});
			
			// Checkout Process Order
			$('#checkout-process-btn').click(function(){
				if ($('#accept-terms:checked').val() !== undefined) {
					var btn_link = $(this).text();
					$(this).removeClass('green');
					$(this).html(loader3);
					$(this).attr('style','text-decoration:none;');
					$.ajax({
						url:$(this).attr('rel'),
						success: function(data){
							var ajx_res = $('#ajx-res', $(data));
							if(ajx_res.attr('role') == '0'){
								var order_no = ajx_res.attr('title');
								window.location = '/my-cart/order-receipt?order='+order_no;
							}
							$('#order-status').html(ajx_res);
							$('#checkout-process-btn').addClass('green');
							$('#checkout-process-btn').html(btn_link);
							$('#checkout-process-btn').attr('style','');
						}
					});
				}else{
					alert('Please check to accept our Terms & Conditions and proceed with your order.')
				}
				return false;
			});
			
			// Create Account
			$('#create-frm1-btn').click(function() {
				var error = false;
				var uri = getURLParameter('uri');
				
				var email = $('input:text[name=email]').val();
				if (email == ''){
					error = true;
					$('#email-lbl').addClass('error');
					$('#email-fld').addClass('error');
				} else {
					$('#email-lbl').removeClass('error');
					$('#email-fld').removeClass('error');
				}
				var pass1 = $('input:password[name=pass1]').val();
				if (pass1 == ''){
					error = true;
					$('#pass1-lbl').addClass('error');
					$('#pass1-fld').addClass('error');
				} else {
					$('#pass1-lbl').removeClass('error');
					$('#pass1-fld').removeClass('error');
				}
				var pass2 = $('input:password[name=pass2]').val();
				if (pass2 == ''){
					error = true;
					$('#pass2-lbl').addClass('error');
					$('#pass2-fld').addClass('error');
				} else {
					$('#pass2-lbl').removeClass('error');
					$('#pass2-fld').removeClass('error');
				}
				var contactnumber = $('input:text[name=contactnumber]').val();
				if (contactnumber == ''){
					error = true;
					$('#contactnumber-lbl').addClass('error');
					$('#contactnumber-fld').addClass('error');
				} else {
					$('#contactnumber-lbl').removeClass('error');
					$('#contactnumber-fld').removeClass('error');
				}
				var optin = $('#optin-btns label.ui-state-active').text();
				var optinyn = 'N'
				if(optin == 'Yes'){
					var optinyn = 'Y'
				}
				var ccnumber = $('input:text[name=ccnumber]').val();
				if (ccnumber == ''){
					error = true;
					$('#ccnumber-lbl').addClass('error');
					$('#ccnumber-fld').addClass('error');
				} else {
					$('#ccnumber-lbl').removeClass('error');
					$('#ccnumber-fld').removeClass('error');
				}
				var ccexpdatemonth = $('select.ccexpmonths option:selected').val();
				if (ccexpdatemonth == ''){
					error = true;
					$('#ccexpdate-lbl').addClass('error');
					$('#ccexpmonths-fld').addClass('error');
				} else {
					$('#ccexpmonths-fld').removeClass('error');
				}
				var ccexpdateyear = $('select.ccexpyears option:selected').val();
				if (ccexpdateyear == ''){
					error = true;
					$('#ccexpdate-lbl').addClass('error');
					$('#ccexpyears-fld').addClass('error');
				} else {
					$('#ccexpyears-fld').removeClass('error');
				}
				if(ccexpdatemonth != '' && ccexpdateyear != '')
				{
					$('#ccexpdate-lbl').removeClass('error');
					var ccexpdate = ccexpdateyear + ccexpdatemonth;
				}
				var ccvnumber = $('input:text[name=ccvnumber]').val();
				if (ccvnumber == ''){
					error = true;
					$('#ccvnumber-lbl').addClass('error');
					$('#ccvnumber-fld').addClass('error');
				} else {
					$('#ccvnumber-lbl').removeClass('error');
					$('#ccvnumber-fld').removeClass('error');
				}
				var billfirstname = $('input:text[name=billfirstname]').val();
				if (billfirstname == ''){
					error = true;
					$('#billfirstname-lbl').addClass('error');
					$('#billfirstname-fld').addClass('error');
				} else {
					$('#billfirstname-lbl').removeClass('error');
					$('#billfirstname-fld').removeClass('error');
				}
				var billlastname = $('input:text[name=billlastname]').val();
				if (billlastname == ''){
					error = true;
					$('#billlastname-lbl').addClass('error');
					$('#billlastname-fld').addClass('error');
				} else {
					$('#billlastname-lbl').removeClass('error');
					$('#billlastname-fld').removeClass('error');
				}
				var billaddress = $('input:text[name=billaddress]').val();
				if (billaddress == ''){
					error = true;
					$('#billaddress-lbl').addClass('error');
					$('#billaddress-fld').addClass('error');
				} else {
					$('#billaddress-lbl').removeClass('error');
					$('#billaddress-fld').removeClass('error');
				}
				var billcity = $('input:text[name=billcity]').val();
				if (billcity == ''){
					error = true;
					$('#billcity-lbl').addClass('error');
					$('#billcity-fld').addClass('error');
				} else {
					$('#billcity-lbl').removeClass('error');
					$('#billcity-fld').removeClass('error');
				}
				var billstate = $('select.billstate option:selected').val();
				if (billstate == ''){
					error = true;
					$('#billstate-lbl').addClass('error');
					$('#billstate-fld').addClass('error');
				} else {
					$('#billstate-lbl').removeClass('error');
					$('#billstate-fld').removeClass('error');
				}
				var billzip = $('input:text[name=billzip]').val();
				if (billzip == ''){
					error = true;
					$('#billzip-lbl').addClass('error');
					$('#billzip-fld').addClass('error');
				} else {
					$('#billzip-lbl').removeClass('error');
					$('#billzip-fld').removeClass('error');
				}
				
				if(error == false) {				
					if(pass1 == pass2) {
						var postdata = 'email='+email;
						postdata = postdata + '&password=' + pass1;
						postdata = postdata + '&contactnumber=' + contactnumber.replace(/\D/g,'');
						postdata = postdata + '&billfirstname=' + billfirstname;
						postdata = postdata + '&billlastname=' + billlastname;
						postdata = postdata + '&billaddress=' + billaddress;
						postdata = postdata + '&billcity=' + billcity;
						postdata = postdata + '&billstate=' + billstate;
						postdata = postdata + '&billzip=' + billzip;
						postdata = postdata + '&optinyn=' + optinyn;
						postdata = postdata + '&ccnumber=' + ccnumber;
						postdata = postdata + '&ccexpdate=' + ccexpdate;
						postdata = postdata + '&ccvnumber=' + ccvnumber;
						$("#createaccount-ajx-msg").html(loader2);
						$.ajax({
							url: '/my-account/create-account/',
							type: 'POST',
							data: postdata,
							success: function(data){
								var ajx_res = $('#ajx-res', $(data));
								$("#createaccount-ajx-msg").html(ajx_res);
								$('input:text[name=ccnumber]').val('');
								if(ajx_res.attr('class') == "success") {
									if(uri != '') {
										window.location = uri;
									}
								}
							}
						});
					} else {
						error = true;
						$('#pass1-lbl').addClass('error');
						$('#pass1-fld').addClass('error');
						$('#pass2-lbl').addClass('error');
						$('#pass2-fld').addClass('error');
						alert('Passwords do not match')
					}
				}
			});
			
			// Update Profile
			$('#update-profile-btn').click(function(){
				var email = $('input:text[name=email]').val();
				var contactnumber = $('input:text[name=contactnumber]').val();
				var billfirstname = $('input:text[name=billfirstname]').val();
				var billlastname = $('input:text[name=billlastname]').val();
				var billaddress = $('input:text[name=billaddress]').val();
				var billcity = $('input:text[name=billcity]').val();
				var billstate = $('select.billstate option:selected').val();
				var billzip = $('input:text[name=billzip]').val();
				var optin = $('#optin-btns label.ui-state-active').text();
				var optinyn = 'N'
				if(optin == 'Yes'){
					var optinyn = 'Y'
				}
				var ccnumber = $('input:text[name=ccnumber]').val();
				var ccexpdatemonth = $('select.ccexpmonths option:selected').val();
				var ccexpdateyear = $('select.ccexpyears option:selected').val();
				var ccexpdate = ccexpdateyear + ccexpdatemonth;
				var ccvnumber = $('input:text[name=ccvnumber]').val();
				
				var postdata = 'email='+email;
					postdata = postdata + '&contactnumber=' + contactnumber.replace(/\D/g,'');
					postdata = postdata + '&billfirstname=' + billfirstname;
					postdata = postdata + '&billlastname=' + billlastname;
					postdata = postdata + '&billaddress=' + billaddress;
					postdata = postdata + '&billcity=' + billcity;
					postdata = postdata + '&billstate=' + billstate;
					postdata = postdata + '&billzip=' + billzip;
					postdata = postdata + '&optinyn=' + optinyn;
					postdata = postdata + '&ccnumber=' + ccnumber;
					postdata = postdata + '&ccexpdate=' + ccexpdate;
					postdata = postdata + '&ccvnumber=' + ccvnumber;
				
				$("#change-status").html(loader2);
				$.ajax({
					url: '/my-account/update-profile/',
					type: 'POST',
						data: postdata,
						success: function(data){
						var ajx_res = $('#ajx-res', $(data)).addClass('done');
						$("#change-status").html(ajx_res);
						if(ajx_res.attr('role') == 'checkout'){
							$('#no-cc-msg').fadeOut(500);
							$('#cart-profile-checkout').fadeIn(500);
							$('#cart-profile-checkout').attr('rel','/my-cart/review-order');
							$('input:text[name=ccnumber]').val('');
							$('input:text[name=ccvnumber]').val('');
						}
					}
				});
				return false;
			});
			
			
			// Customer Care Find A Store
			$('#findstore-btn').click(function(){
				var url = $(this).attr('rel');
				var radius = 5;
				var zipcode = $('#findstore-zipcode').val();
				var zipreg = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
				var iszipcode =  zipreg.test(zipcode);
				if(iszipcode){
					$("#zip-msg-store").fadeOut(500);
					$("#findstore-radius option:selected").each(function () {
						radius = $(this).val();
					});
					var title = "Store Locator Results";
					$("#dialog").dialog({height:400,width:600,modal:true,title:title,resizable:false});
					$("#dialog").html(loader2);
					$.ajax({
						url: url,
						type: 'POST',
						data: 'zipcode='+zipcode+'&radius='+radius,
						success: function(data){
							var div = $('#ajx-response', $(data)).addClass('done');
							$("#dialog").html(div);
						}
					});
				} else {
					$("#zip-msg-store").hide();
					$("#zip-msg-store").addClass('error');
					$("#zip-msg-store").html('Please specify a valid postal/zip code');
					$("#zip-msg-store").fadeIn(500);
				}
				
			});
			
			// Customer Care Coverage Maps
			$('#coverage-maps-btn').click(function() {
				var zipcode = $('#coverage-maps-zipcode').val();
				var zipreg = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
				var iszipcode =  zipreg.test(zipcode);
				if(iszipcode){
					var url = $(this).attr('rel')+'?zipcode='+zipcode;
					$("#zip-msg-coverage").fadeOut(500);
					var title = "Coverage Map Results";
					$("#dialog").dialog({height:625,width:625,modal:true,title:title,resizable:false});
					$("#dialog").html(loader2);
					$.ajax({
						url: url,
						type: 'GET',
						success: function(data){
							var div = $('#ajx-response', $(data)).addClass('done');
							$("#dialog").html(div);
						}
					});
				} else {
					$("#zip-msg-coverage").hide();
					$("#zip-msg-coverage").addClass('error');
					$("#zip-msg-coverage").html('Please specify a valid postal/zip code');
					$("#zip-msg-coverage").fadeIn(500);
				}
				
			});
			
			
			// Activate Phone (Load webpage)
			/*
			$('#activate-btn').click(function(){
				var title = "Activate Your Phone";
				$("#dialog").dialog({height:600,width:825,modal:true,title:title,resizable:false});
				$("#dialog").html('<iframe id="activate-frame" src="https://www.iwirelesshome.com/activate.php" width="795" height="555"></iframe>');
				$('#activate-frame').ready(function() {
					var contents = $('#activate-frame').contents();
					contents.scrollTop(-500);
				});
			});
			*/
			
			// Loyalty Rewards My Account
			$('#loyalty-details-btn').click(function(){
				var title = $('#loyalty-reward-details').attr('title');
				$("#dialog").html($('#loyalty-reward-details').html());
				$("#dialog").dialog({height:250,width:500,modal:true,title:title,resizable:false}); // Open jQuery UI dialog 
			});
			
			// My account dialog links
			$('a.dialog').click(function(){
				var title = this.title;
				$("#dialog").dialog({height:400,width:600,modal:true,title:title,resizable:false}); // Open jQuery UI dialog 
			});
			
			// Terms and Conditions link in my-cart
			$('#tc-cart').click(function(){
				var title = "Terms and Conditions";
				var url = $(this).attr('rel');
				$("#dialog").dialog({height:430,width:750,modal:true,title:title,resizable:false});
				$("#dialog").html(loader2);
				$.ajax({
					url: url,
					type: 'GET',
					success: function(data){
						var div = $('.pane-node-body', $(data)).addClass('done');
						$("#dialog").html(div);
					}
				});
			});
			
			// International Rates on Plans Page
			$('#international-rates-select').change(function(){
				$('tr.active').fadeOut(500);
				$('tr.rate-row').removeClass('active');
				$("#international-rates-select option:selected").each(function () {
  					var row = '#rate-row-'+$(this).val();
  					$(row).fadeOut(500);
  					$(row).addClass('active');
  					$(row).fadeIn(500);
				});
				return false;
			});
			
			//Family Add Service
			/*$('#family-add-service-btn').click(function(){
				var url = $(this).attr('rel');
				$('#add-service-status').html(loader5);
				$.ajax({
					url: url,
					type: 'GET',
					success: function(data){
						var ajx_res = $('#ajx-res', $(data));
						$("#add-service-status").html(data);
						if(ajx_res.attr('role') == 'success'){
							var lastrow = $('#family-mdn-tbl tr:last');
							var newrowid = lastrow.attr('id') + '0';
							var nrow = '<tr id="'+newrowid+'" style="display:none;">';
								nrow = nrow + '<td>00000</td>';
								nrow = nrow + '<td>&nbsp;</td>';
								nrow = nrow + '<td>00000</td>';
								nrow = nrow + '</tr>';
							lastrow.after(nrow);
							$('#'+newrowid).fadeIn(1000);
						}
					}
				});
				return false;
			});*/
			
			// Family Adding airtime from within the myaccount family plans.
			$('#family-airtime-btn').click(function(){
				$('#autopay').hide();
				$('#add-airtime').toggle('slow', function() {
    				// Animation complete.
  				});
  				return false;
			});
			
			// Family Adding airtime from within the myaccount family plans.
			$('#family-autopay-btn').click(function(){
				$('#add-airtime').hide();
				var billing_type = $('#autopay-billing-btns label.ui-state-active').text();
				$('#autopay').toggle('slow', function() {
					switch(billing_type)
					{
						case 'monthly':
							$('#none-info').hide();
							$('#balance-info').hide();
							$('#monthly-info').fadeIn(500);
							$('#everymonth-info').hide();
	  						break;
	  					case 'every month':
							$('#none-info').hide();
							$('#balance-info').hide();
							$('#monthly-info').hide();
							$('#everymonth-info').fadeIn(500);
	  						break;
	  					case 'low balance':
	  						$('#none-info').hide();
	  						$('#monthly-info').hide();
	  						$('#balance-info').fadeIn(500);
	  						$('#everymonth-info').hide();
	  						break;
	  					case 'no payment':
	  						$('#balance-info').hide();
							$('#monthly-info').hide();
	  						$('#none-info').fadeIn(500);
	  						$('#everymonth-info').hide();
	  						break;
					}
  				});
  				return false;
			});
			
			//Family Topup By CC
			$('#topup-familyplan-select').change(function(){
				var title = "Add Airtime";
				var cc = $("#cc-fld").val();
				if(cc == '1'){
					var cust_num = $("#cust-num-fld").val();
					var amount = $(this).val();
					var mdn = $("#phone-num-fld").val();
					$('#add-airtime-dialog td.amount').html('$'+amount+'.00');
					$.ajax({
						url: '/iwireless/api/topup.php',
						type: 'POST',
						data: 'cust_num='+cust_num+'&amount='+amount+'&mdn='+mdn+'&action=calculate',
						dataType: 'xml',
						success: function(xml){
							var subtotal = $(xml).find('SubTotal').text();
							var taxes = $(xml).find('TaxesTotal').text();
							var total = $(xml).find('GrandTotal').text();
							$('#add-airtime-dialog td.subtotal').html(subtotal);
							$('#add-airtime-dialog td.taxes').html(taxes);
							$('#add-airtime-dialog td.total').html(total);
							$('#airtime-checkout-btn').addClass('green');
						}
					});
					$("#add-airtime-dialog").dialog({height:350,width:600,modal:true,title:title,resizable:false});
					$('#airtime-checkout-btn').click(function(){
						var checkout_link  = $(this).html();
						$(this).removeClass('green');
						$(this).html(loader5);
						$(this).attr('style','text-decoration:none;');
						$.ajax({
							url: '/iwireless/api/topup.php',
							type: 'POST',
							data: 'cust_num='+cust_num+'&amount='+amount+'&mdn='+mdn+'&action=checkout',
							dataType: 'xml',
							success: function(xml2){
								var order_num = $(xml2).find('OrderNo').text();
								var result_code = $(xml2).find('ResultCode').text();
								var problem_desc = $(xml2).find('ProblemDesc').text();
								$('#add-airtime-dialog td.order-num').html(order_num);
								$('#taxes-totals-tbl').hide();
								$('#checkout-tbl').hide();
								if(result_code != '0'){
									$('#add-airtime-dialog td.order-num').html('');
									$('#add-airtime-dialog td.result').html('An error occurred while trying to process your credit card. Please verify your credit card and billing information in account profile. ');
									$('#add-airtime-dialog td.subtotal').html('');
									$('#add-airtime-dialog td.taxes').html('');
									$('#add-airtime-dialog td.total').html('');
								}
								$('#order-tbl').fadeIn(500);
								$('#close-dialog-btn').click(function(){
									$("#add-airtime-dialog").dialog('destroy');
									$('#taxes-totals-tbl').show();
									$('#checkout-tbl').show();
									$('#order-tbl').hide();
									$('#airtime-checkout-btn').html(checkout_link);
									getFamilyCost();
									return false;
								});
							}
						});
						return false;
					});
				}else{
					//alert('Please update your profile with valid billing information.');
					$('#family-add-airtime-status').addClass('error');
					$('#family-add-airtime-status').html('Please click <a href="/my-account/update-profile/">here</a> to update your account with a valid credit card.')
				}
			});
			
			//Family Redeem Airtime
			$('#family-redeem-airtime-btn').click(function(){
				var redeem_link  = $(this).html();
				$(this).removeClass('green');
				$(this).html(loader5);
				$(this).attr('style','text-decoration:none;');
				var mdn = $('#family-redeem-airtime-mdn').val();
				var pin = $('#family-redeem-airtime-pin').val();;
				$.ajax({
					url: '/iwireless/api/topup.php',
					type: 'POST',
					data: 'mdn='+mdn+'&pin='+pin+'&action=redeem',
					dataType: 'xml',
					success: function(xml){
						var result_code = $(xml).find('ResultCode').text();
						var problem_desc = $(xml).find('ProblemDesc').text();
						$('#family-redeem-airtime-btn').html(redeem_link);
						$('#family-redeem-airtime-btn').addClass('green');
						if(result_code == '0'){
							getFamilyCost();
							$('#family-redeem-airtime-status').addClass('success');
							$('#family-redeem-airtime-status').html('Success!');
						}else{
							$('#family-redeem-airtime-status').addClass('error');
							$('#family-redeem-airtime-status').html(problem_desc);
							$('#family-redeem-airtime-pin').val('');
						}
					}
				});
				return false;
			});
			
			
			//Family Plan Radio Buttons
			$("input[name=family-plan]").change(function () {
				getFamilyCost();
				return false;
			});
			
			//Family Service
			$("#add-phone-box input[type='text']").change(function () {
				numberchange($(this));
				return false;
			});
			
			//Family Service
			$("#add-phone-box input[type='password']").change(function () {
				passwordchange($(this));
				return false;
			});
			
			// Create Family Plan
			$('#create-familyplan-btn').click(function(){
				var phone1 = $('#s-0').val().replace(/\D/g,'');
				var phone2 = $('#s-1').val().replace(/\D/g,'');
				var phone3 = $('#s-2').val().replace(/\D/g,'');
				var phone4 = $('#s-3').val().replace(/\D/g,'');
				var phone5 = $('#s-4').val().replace(/\D/g,'');
				var pass1 = $('#sp-0').val().replace(/\D/g,'');
				var pass2 = $('#sp-1').val().replace(/\D/g,'');
				var pass3 = $('#sp-2').val().replace(/\D/g,'');
				var pass4 = $('#sp-3').val().replace(/\D/g,'');
				var pass5 = $('#sp-4').val().replace(/\D/g,'');
				var planid = $("input[name=family-plan]:checked").val();
				$('#create-familyplan-btn').hide();
				$('#status-message').html(loader5);
				$.ajax({
					url: '/iwireless/api/create_familyplan.php',
					type: 'POST',
					data: 'phone1='+phone1+'&phone2='+phone2+'&phone3='+phone3+'&phone4='+phone4+'&phone5='+phone5+'&pass1='+pass1+'&pass2='+pass2+'&pass3='+pass3+'&pass4='+pass4+'&pass5='+pass5+'&plan_id='+planid,
					dataType: 'xml',
					success: function(xml){
						var result_code = $(xml).find('ResultCode').text();
						var problem_desc = $(xml).find('ProblemDesc').text();
						if(result_code == '0'){
							$('#status-message').addClass('success');
							$('#status-message').html('Success! Your family plan is in the process of being created, please allow up to 15 minutes for your new family plan to appear on your account.');
							$('#create-familyplan-btn').hide();
							$('#refresh-btn2').fadeIn(500);
						}else{
							$('#status-message').addClass('error');
							$('#status-message').html(problem_desc);
							$('#create-familyplan-btn').show();
						}
					}
				});
				return false;
			});
			
			//Remove Account
			$('#remove-acct-btn').click(function(){
				var title = 'Remove Family Plan Confirmation';
				var mdn = $('#s-0').val().replace(/\D/g,'');
				$( "#dialog" ).html('<p>Are you sure you want to remove your family plan?</p><div id="dialog-status">&nbsp;</div>');
				$( "#dialog" ).dialog({
					resizable: false,
					height:160,
					modal: true,
					buttons: {
						OK: function() {
							$("#dialog-status").html(loader5);
							$.ajax({
								url: '/iwireless/api/family_cancel_account.php',
								dataType: 'xml',
								type: 'POST',
								data: 'mdn='+mdn,
								success: function(xml){
									var result_code = $(xml).find('ResultCode').text();
									var problem_desc = $(xml).find('ProblemDesc').text();
									if(result_code =='0'){
										$( "#dialog" ).dialog('destroy');
										window.location = '/my-account/overview/?action=famcancel';
									}
								}
							});
						},
						Cancel: function() {
							 $(this).dialog('destroy');
						}
					}
				});
				return false;
			});
			
			// Remove Service
			$('.family-removeservice-btn').click(function(){
				var arr = $(this).attr('id').split('-');
				var service = arr[1];
				var pmdn = $('#s-0').val().replace(/\D/g,'');
				var cmdn =  $('#s-'+service).val().replace(/\D/g,'');
				var remove_btn = $(this);
				var remove_btn_html = $(this).html();
				$(this).html(loader5);
				$(this).removeClass('gray');
				$(this).attr('style','text-decoration:none;');
				$.ajax({
					url: '/iwireless/api/family_remove_service.php',
					type: 'POST',
					data: 'pmdn='+pmdn+'&cmdn='+cmdn,
					dataType: 'xml',
					success: function(xml){
						var reslut_code = $(xml).find('ResultCode').text();
						var problem_desc = $(xml).find('ProblemDesc').text();
						var input_text_field = '<input type="text" name="s-'+service+'" id="s-'+service+'" value="" class="service-number">';
						var input_pass_field = '<input type="password" maxlength="4" name="sp-'+service+'" id="sp-'+service+'" value="">';
						var nrow = '<td><label for="s-'+service+'">Phone Number:</label>'+input_text_field +'</td>';
						nrow = nrow + '<td><label for="sp-'+service+'">Passcode:</label>'+input_pass_field +'</td>';
						nrow = nrow + '<td colspan="3" id="std-'+service+'">'+problem_desc+'</td>';
						$('#member-1-tr').html(nrow);
						$("#add-phone-box input[type='text']").change(function () {
							numberchange($(this));
							return false;
						});
						$("#add-phone-box input[type='password']").change(function () {
							passwordchange($(this));
							return false;
						});
					}
				});
				return false;
			});
			
			// Check if service field has a proper passcode.
			function checkPasscode(service){
				var isfamily = $('#isfamily').val();
				var msg = "";
				var ok = '<img src="/sites/all/themes/wire/img/check.png" />';
				if(isfamily){
					ok = '<a href="#" class="green family-addservice-btn">Add Line</a>';
				}
				var error = '<span class="error">passcode required</span>';
				switch(service){
					case '0':
						msg = ($('#sp-0').val() != '') ? ok : error;
						$('#std-0').html(msg);
						break;
					case '1':
						msg = ($('#sp-1').val() != '') ? ok : error;
						$('#std-1').html(msg);
						break;
					case '2':
						msg = ($('#sp-2').val() != '') ? ok : error;
						$('#std-2').html(msg);
						break;
					case '3':
						msg = ($('#sp-3').val() != '') ? ok : error;
						$('#std-3').html(msg);
						break;
					case '4':
						msg = ($('#sp-4').val() != '') ? ok : error;
						$('#std-4').html(msg);
						break;
				}
				if(isfamily){
					// Add Service
					$('.family-addservice-btn').click(function(){
						var pmdn = $('#s-0').val().replace(/\D/g,'');
						var cmdn =  $('#s-'+service).val().replace(/\D/g,'');
						var cpass =  $('#sp-'+service).val().replace(/\D/g,'');
						var add_btn = $(this);
						//var add_btn_html = $(this).html();
						var title = 'Add Line To Family Confirmation';
						$( "#dialog" ).html('<p>Are you sure you want to add an additional line to your family plan?<br /><br />The cost will be immediately deducted from your account balance.</p>');
						$( "#dialog" ).dialog({
							resizable: false,
							modal: true,
							buttons: {
								OK: function() {
									$.ajax({
										url: '/iwireless/api/family_add_service.php',
										type: 'POST',
										data: 'pmdn='+pmdn+'&cmdn='+cmdn+'&cpass='+cpass,
										dataType: 'xml',
										success: function(xml){
											$('#dialog').dialog('destroy');
											add_btn.fadeOut(500);
											var reslut_code = $(xml).find('ResultCode').text();
											var problem_desc = $(xml).find('ProblemDesc').text();
											if(reslut_code == '0'){
												var nrow = '<td>'+cmdn+'</td>';
													nrow = nrow + '<td>&nbsp;</td>';
													nrow = nrow + '<td colspan="3" id="std-'+service+'"><p>The line ['+cmdn+'] has been added successfully.</p>';
													nrow = nrow + '<p>Please click the refresh my account button to see your current balance.</p></td>';
													$('#member-'+service+'-tr').html(nrow);
													getFamilyCost();
											}else{
												$('#std-'+service).addClass('error');
												$('#std-'+service).html('<span class="msg" style="display:none;">'+problem_desc+'</span>');
												$('#std-'+service+' span.msg').fadeIn(500);
												$('#std-'+service+' span.msg').fadeOut(10000)
												if(reslut_code == '4501'){
													$('#add-airtime').show();
												}
												$('#std-'+service+' span.msg').fadeOut('slow', function() {
													checkPasscode(service);
												});
											}
										}
									});
								},
								Cancel: function() {
									 $(this).dialog('destroy');
								}
							}
						});
						return false;
					});
				}
			}
			
			// Update or Change family plan
			$('#update-familyplan-btn').click(function(){
				var mdn = $('#s-0').val();
				var cust_num = $('#cust_num').val();;
				var planid = $("input[name=family-plan]:checked").val();
				$(this).hide()
				$('#change-family-status').show();
				$('#change-family-status').html(loader5);
				$.ajax({
					url: '/iwireless/api/family_change_plan.php',
					type: 'POST',
					data: 'cust_num='+cust_num+'&mdn='+mdn+'&planid='+planid,
					dataType: 'xml',
					success: function(xml){
						var reslut_code = $(xml).find('ResultCode').text();
						var problem_desc = $(xml).find('ProblemDesc').text();
						if(reslut_code == '0'){
							$('#change-family-status').removeClass('error');
							$('#change-family-status').addClass('success');
							$('#change-family-status').html('<p>Success!</p><p>Your plan is in the process of being changed, please allow up to 30 minutes for your new plan to appear on you account. You can always click the "Refresh My Account" button to update your information.</p>');
						}else{
							$('#change-family-status').removeClass('success');
							$('#change-family-status').addClass('error');
							$('#change-family-status').html(problem_desc);
							$('#add-airtime').show();
							$('#change-family-status').fadeOut(15000, function() {
								$('#update-familyplan-btn').show();
								$(this).removeClass('error');
							});
						}
					}
				});
				return false;
			});
			
			// Print Order
			$('#printorder-btn').click(function(){
				var w = window.open('', 'my div', 'height=400,width=600');
    				w.document.write('<html><head><title>ORDER: '+$(this).attr('rel')+'</title>');
   				 	w.document.write('<link rel="stylesheet" href="sites/all/themes/wire/css/print.css" type="text/css" />');
    				w.document.write('</head><body >');
    				w.document.write($('#receipt').html());
    				w.document.write('</body></html>');
    				w.document.close();
    				w.print();
    			return true;
			});
			
			/* ACTIVATION */
			
			// Zipcode Question
			$('#act-q-zipcode').click(function(){
				$('#zip-status').html('<div class="info">This is the primary zip code where you will be using your phone. Please input the first five digits of your ZIP code only.</div>');
				$('#zip-status').show('slow', function() {
					// Animation complete.
  				});
				return false;
			});
			
			// ESN Question
			$('#act-q-esn').click(function(){
				$('#esn-status').html('<div class="info">The ESN is represented by 11 or 18 numbers (like 33610254897) and can be found on the back of your handset under the battery. Click <a id="esn-ex-btn" href="#">here</a> to see example.<div id="esn-ex" style="display:none;"><img src="/sites/all/themes/wire/img/esn-ex.gif" /></div></div>');
					$('#esn-status').show('slow', function() {
						$('#esn-ex-btn').click(function(){
						$('#esn-ex').toggle('slow', function() {
	    					// Animation complete.
	  					});
						return false;
					});
  				});
				return false;
			});
			
			// Passcode Question
			$('#act-q-psc').click(function(){
				$('#psc-status').html('<div class="info">For security reasons, you must set up a 4-digit passcode. Enter a 4-digit number of your choice. Choose a number that is easy to remember, but nothing too obvious like your birthday or 1234. You can change your passcode at any any time by logging into you account after your phone is activated.</div>');
				$('#psc-status').show('slow', function() {
					// Animation complete.
				});
				return false;
			});
			
			// Zipcode
			$('#id_zip').change(function(){
				var zip_code = $('#id_zip').val();
				var info_icon = $('#act-q-zipcode').html();
				var int_regex = /^\d+$/;
				if(int_regex.test(zip_code)) {
					if(zip_code.length == 5){
						$('#act-q-zipcode').html(loader6);
						$.ajax({
							url: '/iwireless/api/activate_get_coverage.php',
							type: 'POST',
							data: 'zip='+zip_code,
							success: function(data){
								var reslut_code = $(data).attr('role');
								if(reslut_code == '0'){
									$('#act-q-zipcode').html('<img src="/sites/all/themes/wire/img/check.png" />');
									$('#zip-status').html($(data));
									$('#zip-status').fadeIn(500);
									$('#id_esn').focus();
									$('#id_zip').removeClass('error');
								}else{
									$('#zip-status').html($(data));
									$('#act-q-zipcode').html('<img alt="" src="/sites/all/themes/wire/img/icon-question.png">');
									$('#id_zip').addClass('error');
								}
								
							}
						});
					}else{
						$('#zip-status').html('<div class="error">Zipcode is not 5 digets</div>');
						$('#id_zip').addClass('error');
					}
				}else{
					$('#act-q-zipcode').html('<img alt="" src="/sites/all/themes/wire/img/icon-question.png">');
					$('#zip-status').html('<div class="error">Must be a valid zipcode.</div>');
					$('#id_zip').addClass('error');
				}
				return false;
			});
			
			// ESN
			$('#id_esn').change(function(){
				var esn = $('#id_esn').val();
				var info_icon = $('#act-q-esn').html();
				var int_regex = /^\d+$/;
				if(int_regex.test(esn)) {
					$('#act-q-esn').html(loader6);
					$.ajax({
						url: '/iwireless/api/activate_get_handset_info.php',
						type: 'POST',
						data: 'esn='+esn,
						success: function(data){
							var reslut_code = $(data).attr('role');
							var shopper_eligible = $(data).attr('rel');
							$('#act-q-esn').html(info_icon);
							$('#esn-status').html($(data));
							$('#esn-status').fadeIn(500);
							if(reslut_code == '0'){
								$('#act-q-esn').html('<img src="/sites/all/themes/wire/img/check.png" />');
								$('#id_esn').removeClass('error');
								$('#esn-status').html($(data));
								$('#esn-status').fadeIn(1000);
								$('#id_psc').focus();
							}else{
								$('#id_esn').addClass('error');
								$('#act-q-esn').html('<img alt="" src="/sites/all/themes/wire/img/icon-question.png">');
							}
						}
					});
				}else{
					$('#act-q-esn').html('<img alt="" src="/sites/all/themes/wire/img/icon-question.png">');
					$('#esn-status').html('<div class="error">Must be a number.</div>');
					$('#id_esn').addClass('error');
				}
				return false;
			});
			
			// Passcode
			$('#id_psc').change(function(){
				var esn = $('#id_esn').val();
				var zip = $('#id_zip').val();
				var psc = $('#id_psc').val();
				var info_icon = $('#act-q-psc').html();
				var int_regex = /^\d+$/;
				if(int_regex.test(psc)) {
					if(psc.length == 4){
						$('#psc-status').html('');
						$('#act-q-psc').html('<img src="/sites/all/themes/wire/img/check.png" />');
						$('#psc-status').html('<div class="success">Your passcode can be changed in My Account after your phone is activated.</div>');
						$('#psc-status').fadeIn(1000);
						$('#id_psc').removeClass('error');
					}else{
						$('#psc-status').html('<div class="error">Please enter a 4-digit number.</div>');
						$('#id_psc').addClass('error');
					}
				}else{
					$('#psc-status').html('<div class="error">Please enter a 4-digit number.  </div>');
					$('#id_psc').addClass('error');
				}
				return false;
			});
			
			// Activate Button
			$('#activate-now-btn').click(function(){
				var error = check_activation();
				if(error){
					alert('There is an error. Ensure you have properly entered a valid zipcode, esn, and passcode for activation.');
				}else{
					var esn = $('#id_esn').val();
					var zip = $('#id_zip').val();
					var psc = $('#id_psc').val();
					var activate = $("#activate-box").html();
					$("#activate-box").html(loader5);
					$.ajax({
						url: '/iwireless/api/activate_activate.php',
						type: 'POST',
						data: '&esn='+esn+'&zip='+zip+'&psc='+psc,
						success: function(data){
							var reslut_code = $(data).attr('role');
							if(reslut_code == '0'){
								//var res = $('#res', $(data));
								var mdn = $(data).attr('rel');
								$("#congrats-status").html(data);
								$('#step1').fadeOut(500, function() {
									$("#congrats").fadeIn(500);
									$('#activate-login-btn').click(function(){
									    var userid = mdn;
									    var pcde = $('#id_psc').val();
									    $('#actions-box').html(loader2);
									    $.ajax({
											url: '/my-account/ajx-login',
											type: 'POST',
											data: 'userid='+userid+'&pcde='+pcde,
											success: function(data2){
												var div = $('#msg', $(data2)).addClass('done');
												var statusmsg = div.attr('title');
												window.location = '/my-account/overview/';
												//if(statusmsg == "error"){
												//	
												//}else{
												//	window.location = '/my-account/overview/';
												//}
											}	
										});
										return false;
									});
								});				
							}else{
								$("#activate-box").html(activate);
								$("#activate-status").fadeOut(10000);
							}
						}
					});
				}
				return false;
			});
			
			// Remove CC from profile
			$('#remove-cc-link').click(function(){
				var url = $(this).attr('rel');
				var title = 'Remove Credit Card';
				$( "#dialog" ).html('<p>Are you sure you want to remove your credit card from your profile?</p><div id="remove-cc-status"></div>');
				$( "#dialog" ).dialog({
					resizable: false,
					height:160,
					modal: true,
					buttons: {
						OK: function() {
							$("#remove-cc-status").html(loader5);
							$.ajax({
								url: url,
								dataType: 'xml',
								type: 'GET',
								success: function(xml){
									var result_code = $(xml).find('ResultCode').text();
									var problem_desc = $(xml).find('ProblemDesc').text();
									if(result_code =='0'){
										$( "#dialog" ).dialog('destroy');
										window.location = '/my-account/overview/?action=refresh';
									}
								}
							});
						},
						Cancel: function() {
							 $(this).dialog('destroy');
						}
					}
				});
				return false;
			});
			
			// Check if all variables are ok for activation.
			function check_activation(){
				var check = '/sites/all/themes/wire/img/check.png';
				
				var zip = $('#act-q-zipcode img').attr('src');
				var esn = $('#act-q-esn img').attr('src');
				var psc = $('#act-q-psc img').attr('src');
				
				var zip_error = (zip == check) ? false : true;
				var esn_error = (esn == check) ? false : true;
				var psc_error = (psc == check) ? false : true;
				
				if(zip_error || esn_error || psc_error){
					return true;
				}else{
					return false;
				}
			}
			
			// Change add service phone number field change function
			function numberchange(nfield){
				getFamilyCost();
				var arr = nfield.attr('id').split('-');
				if(nfield.val() != ''){
					checkPasscode(arr[1]);
				}else{
					var pfield = '#sp-'+arr[1];
					var td = '#std-'+arr[1];
					$(pfield).val('');
					$(td).html('&nbsp;');
				}
			}
			
			//Change add service password field change function
			function passwordchange(pfield){
				var arr = pfield.attr('id').split('-');
				var mdn = '#s-'+arr[1];
				var td = '#std-'+arr[1];
				if($(mdn).val() != ''){
					checkPasscode(arr[1]);
				}else{
					//$(td).html('mobile number required');
					pfield.val('');
				}
			}
			
			// Update Family Plan Cost
			function getFamilyCost(){
				var pmdn = $('#s-0').val();
				var planid = $("input[name=family-plan]:checked").val();
				var cmdn1 = $('#s-1').val();
				var cmdn2 = $('#s-2').val();
				var cmdn3 = $('#s-3').val();
				var cmdn4 = $('#s-4').val();
				var autopay = $('#autopay-status').attr('for');
				$('#balance-amount').html(loader5);
				$('#family-plan-amount').html(loader5);
				$('#status-message').html(loader5);
				var isfamily = $('#isfamily').val();
				$.ajax({
					url: '/iwireless/api/family_get_cost.php',
					type: 'POST',
					data: 'pmdn='+pmdn+'&planid='+planid+'&cmdn1='+cmdn1+'&cmdn2='+cmdn2+'&cmdn3='+cmdn3+'&cmdn4='+cmdn4+'&isfamily='+isfamily+'&autopay='+autopay,
					dataType: 'xml',
					success: function(xml){
						var balance_amount = '$'+$(xml).find('acctbalance').text();
						var plan_cost = '$'+$(xml).find('plancost').text();
						var status = $(xml).find('status').text();
						var status_message = $(xml).find('message').text();
						var status_class = $(xml).find('class').text();
						$('#balance-amount').html(balance_amount);
						$('#family-plan-amount').html(plan_cost);
						$('#autopay-amount').html(plan_cost);
						$('#status-message').html(status_message);
						$('#status-message').removeClass();
						$('#status-message').addClass(status_class);
						/*if(status == '1'){
							$('#update-familyplan-btn').show();
							$('#create-familyplan-btn').show();
							$('#add-airtime').hide();
							
						}else{
							$('#update-familyplan-btn').hide();
							$('#create-familyplan-btn').hide();
						}*/
					}
				});
			}
			
			function getURLParameter(name) {
    			return decodeURI(
        		(RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
    			);
    		}
    		
    		function printwindow(data, title){
    			alert('window print');
    			//var w = window.open();
    			//	if (!w) {
      			//		alert('You have a popup blocker enabled. Please allow popups for www.iwirelesshome.com');
      			//	}
		        //	w.document.write('<html><head><title>'+title+'</title>');
		        //	w.document.write('<link rel="stylesheet" href="print.css" type="text/css" />');
		        //	w.document.write('</head><body >');
		        //	w.document.write(data);
		        //	w.document.write('</body></html>');
		        //	w.document.close();
		        //	w.print();
		        return true;
    		}
    		
    		function login(formid){
    			var pathname = window.location.pathname;
    			var uri = getURLParameter('uri');
    			var formIsValid = true;
    			var userid = '';
    			var pcde = '';
    			var status = '';
    			//var formid = $(this).attr('id');
    			
    			if(formid == 'login-frm1-btn') {
    				userid = $("#userid-frm1").val();
    				pcde = $("#pcde-frm1").val();
    				status = $('#login-status-frm1');
    			} else {
    				userid = $("#userid").val();
    				pcde = $("#pcde").val();
    				status = $('#login-status');
    			}
    			
    			if(pcde == 'Passcode'){
    				formIsValid = false;
    			}
    			
    			if(userid == 'Email or Phone #'){
    				formIsValid = false;
    			}
    			
    			if(formIsValid){
    				var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    				var	isemail = emailReg.test(userid);
    				if(isemail == false){
    					userid = userid.replace(/\D/g,'');
    				}	
    				
    				$('.login-frm-btn').hide();
	    			$('.login-loader').fadeIn(500);
	    			
	    			
	    			$.ajax({
	  					url: '/my-account/ajx-login',
	  					type: 'POST',
	  					data: 'userid='+userid+'&pcde='+pcde,
	  					success: function(data){
	  						var div = $('#msg', $(data)).addClass('done');
	    					var statusmsg = div.attr('title');
	    					$('.login-loader').hide();
	    					$('.login-frm-btn').fadeIn(500);
	    					if(statusmsg == "error"){
	    						status.html(div);
	    						status.fadeIn(500);
								status.delay(3000).fadeOut(500);
	    					}else{
	    						if(statusmsg == "datacard"){
									var title = 'Datacard Account';
									$( "#dialog" ).html(div);
									$( "#dialog" ).dialog({
										resizable: false,
										height:260,
										modal: true,
										buttons: {
											Close: function() {
												window.location = '/my-account/logout';
											}
										}
									});	    							
	    						}else{
		    						if(formid == 'login-frm1-btn') {
		    							if(uri != 'null') {
		    								window.location = uri;
		    							} else {
		    								window.location = '/my-account/';
		    							}
		    						} else {
		    							$('#login-form').hide();
		    							$('#login-box div.b').html(div);
		    							if(pathname == '/my-cart/'){
		    								location.reload(true);
		    							}
		    						}
	    						}
	    					}
	  					}	
					});
				}else{
					status.html('<div id="msg" title="error">Please ensure you have entered a proper phone number and or email.</div>');
					status.fadeIn(500);
					status.delay(3000).fadeOut(500);
				}
    		}

		// CONTEXT FUNCTIONS END =====================
		}
	};
})(jQuery);
;

