/*
 * jQuery Impromptu
 * By: Trent Richardson [http://trentrichardson.com]
 * Version 1.5
 * Last Modified: 3/31/2008
 * 
 * Copyright 2008 Trent Richardson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
jQuery.extend({	
	ImpromptuDefaults: { prefix:'jqi', buttons:{ Ok:true }, loaded:function(){}, submit:function(){return true;}, callback:function(){}, opacity:0.6, zIndex: 999, overlayspeed:'slow', promptspeed:'fast', show:'show', focus:0, useiframe:false },
	SetImpromptuDefaults: function(o){ 
		jQuery.ImpromptuDefaults = jQuery.extend({},jQuery.ImpromptuDefaults,o);
	},
	prompt: function(m,o){
		o = jQuery.extend({},jQuery.ImpromptuDefaults,o);
		
		var ie6 = (jQuery.browser.msie && jQuery.browser.version < 7);	
		var b = jQuery(document.body);
		var w = jQuery(window);
		
		
		
		var msgbox = '<div class="'+ o.prefix +'box" id="'+ o.prefix +'box">';		
		if(o.useiframe && ((jQuery.browser.msie && jQuery('object, applet').length > 0) || ie6))//if you want to use the iframe uncomment these 3 lines
			msgbox += '<iframe src="javascript:;" class="'+ o.prefix +'fade" id="'+ o.prefix +'fade"></iframe>';
		else{ 
			if(ie6) jQuery('select').css('visibility','hidden');
			msgbox +='<div class="'+ o.prefix +'fade" id="'+ o.prefix +'fade"></div>';
		}	
		msgbox += '<div class="'+ o.prefix +'" id="'+ o.prefix +'"><div class="'+ o.prefix +'container"><div class="'+ o.prefix +'close">X</div><div class="'+ o.prefix +'message">'+ m +'</div><div class="'+ o.prefix +'buttons" id="'+ o.prefix +'buttons">';
		jQuery.each(o.buttons,function(k,v){ msgbox += '<button name="'+ o.prefix +'button'+ k +'" id="'+ o.prefix +'button'+ k +'" value="'+ v +'">'+ k +'</button>'}) ;
		msgbox += '</div></div></div></div>';
		
		var jqib =b.append(msgbox).children('#'+ o.prefix +'box');
		var jqi = jqib.children('#'+ o.prefix);
		var jqif = jqib.children('#'+ o.prefix +'fade');

		var getWindowScrollOffset = function(){ 
			return (document.documentElement.scrollTop || document.body.scrollTop) + 'px'; 
		};		
		
		var getWindowSize = function(){ 
			var size = {
				width: window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth),
				height: window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight)
			};
			return size;
		};
		
		var ie6scroll = function(){ 
			jqib.css({ top: getWindowScrollOffset() }); 
		};
		
		var flashPrompt = function(){
			var i = 0;
			jqib.addClass(o.prefix +'warning');
			var intervalid = setInterval(function(){ 
				jqib.toggleClass(o.prefix +'warning');
				if(i++ > 1){
					clearInterval(intervalid);
					jqib.removeClass(o.prefix +'warning');
				}
			}, 100);			
		};		
		

		var escapeKeyClosePrompt = function(e){
			var kC = (window.event) ? event.keyCode : e.keyCode; // MSIE or Firefox?
			var Esc = (window.event) ? 27 : e.DOM_VK_ESCAPE; // MSIE : Firefox
			if(kC==Esc) removePrompt();
		};

		var positionPrompt = function(){
			var wsize = getWindowSize();
			jqib.css({ position: (ie6)? "absolute" : "fixed", height: wsize.height, width: "100%", top: (ie6)? getWindowScrollOffset():0, left: 0, right: 0, bottom: 0 });
			jqif.css({ position: "absolute", height: wsize.height, width: "100%", top: 0, left: 0, right: 0, bottom: 0 });
			jqi.css({ position: "absolute", top: "100px", left: "50%", marginLeft: ((((jqi.css("paddingLeft").split("px")[0]*1) + jqi.width())/2)*-1) });					
		};
		
		var stylePrompt = function(){
			jqif.css({ zIndex: o.zIndex, display: "none", opacity: o.opacity });
			jqi.css({ zIndex: o.zIndex+1, display: "none" });
		}
		
		var removePrompt = function(callCallback, clicked, msg){
			jqi.remove(); 
			if(ie6)b.unbind('scroll',ie6scroll);//ie6, remove the scroll event
			w.unbind('resize',positionPrompt);			
			jqif.fadeOut(o.overlayspeed,function(){
				jqif.unbind('click',flashPrompt);
				jqif.remove();
				if(callCallback) o.callback(clicked,msg);
				jqib.unbind('keypress',escapeKeyClosePrompt);
				jqib.remove();
				if(ie6 && !o.useiframe) $('select').css('visibility','visible');
			});
		}
		
		positionPrompt();
		stylePrompt();	

		//Events
		jQuery('#'+ o.prefix +'buttons').children('button').click(function(){ 
			var msg = jqi.children('.'+ o.prefix +'container').children('.'+ o.prefix +'message');
			var clicked = o.buttons[jQuery(this).text()];	
			if(o.submit(clicked,msg))				
				removePrompt(true,clicked,msg);
		});
		if(ie6) w.scroll(ie6scroll);//ie6, add a scroll event to fix position:fixed
		jqif.click(flashPrompt);
		w.resize(positionPrompt);
		jqib.keypress(escapeKeyClosePrompt);
		jqi.find('.'+ o.prefix +'close').click(removePrompt);
		
		//Show it
		jqif.fadeIn(o.overlayspeed);
		jqi[o.show](o.promptspeed,o.loaded);
		jqi.find('#'+ o.prefix +'buttons button:eq('+ o.focus +')').focus();//focus the default button
		return jqib;
	}	
});

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(2($){$.c.f=2(p){p=$.d({g:"!@#$%^&*()+=[]\\\\\\\';,/{}|\\":<>?~`.- ",4:"",9:""},p);7 3.b(2(){5(p.G)p.4+="Q";5(p.w)p.4+="n";s=p.9.z(\'\');x(i=0;i<s.y;i++)5(p.g.h(s[i])!=-1)s[i]="\\\\"+s[i];p.9=s.O(\'|\');6 l=N M(p.9,\'E\');6 a=p.g+p.4;a=a.H(l,\'\');$(3).J(2(e){5(!e.r)k=o.q(e.K);L k=o.q(e.r);5(a.h(k)!=-1)e.j();5(e.u&&k==\'v\')e.j()});$(3).B(\'D\',2(){7 F})})};$.c.I=2(p){6 8="n";8+=8.P();p=$.d({4:8},p);7 3.b(2(){$(3).f(p)})};$.c.t=2(p){6 m="A";p=$.d({4:m},p);7 3.b(2(){$(3).f(p)})}})(C);',53,53,'||function|this|nchars|if|var|return|az|allow|ch|each|fn|extend||alphanumeric|ichars|indexOf||preventDefault||reg|nm|abcdefghijklmnopqrstuvwxyz|String||fromCharCode|charCode||alpha|ctrlKey||allcaps|for|length|split|1234567890|bind|jQuery|contextmenu|gi|false|nocaps|replace|numeric|keypress|which|else|RegExp|new|join|toUpperCase|ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('|'),0,{}));

﻿/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the onMouseOver event.
* 
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* hoverIntent is currently available for use in all personal or commercial 
* projects under both MIT and GPL licenses. This means that you can choose 
* the license that best suits your project, and use it accordingly.
* 
* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
* $("ul li").hoverIntent( showNav , hideNav );
* 
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
*	sensitivity: 2, // number = sensitivity threshold (must be 1 or higher)
*	interval: 50,   // number = milliseconds of polling interval
*	over: showNav,  // function = onMouseOver callback (required)
*	timeout: 100,   // number = milliseconds delay before onMouseOut function call
*	out: hideNav    // function = onMouseOut callback (required)
* });
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @return    The object (aka "this") that called hoverIntent, and the event object
* @author    Brian Cherne <brian@cherne.net>
*/
(function($) {
	$.fn.hoverIntent = function(f,g) {
		// default configuration options
		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		// override configuration options with user supplied object
		cfg = $.extend(cfg, g ? { over: f, out: g } : f );

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function(ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).unbind("mousemove",track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				// set previous coordinates for next time
				pX = cX; pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function(e) {
			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
			if ( p == this ) { return false; }

			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({},e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			// else e.type == "onmouseover"
			if (e.type == "mouseover") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX; pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).bind("mousemove",track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}

			// else e.type == "onmouseout"
			} else {
				// unbind expensive mousemove event
				$(ob).unbind("mousemove",track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
		};

		// bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	};
})(jQuery);
/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-12-20 08:46:55 -0600 (Thu, 20 Dec 2007) $
 * $Rev: 4259 $
 *
 * Version: 1.2
 *
 * Requires: jQuery 1.2+
 * 
 */

(function($){
	
$.dimensions = {
	version: '1.2'
};

// Create innerHeight, innerWidth, outerHeight and outerWidth methods
$.each( [ 'Height', 'Width' ], function(i, name){
	
	// innerHeight and innerWidth
	$.fn[ 'inner' + name ] = function() {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		return this.is(':visible') ? this[0]['client' + name] : num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
	};
	
	// outerHeight and outerWidth
	$.fn[ 'outer' + name ] = function(options) {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		options = $.extend({ margin: false }, options || {});
		
		var val = this.is(':visible') ? 
				this[0]['offset' + name] : 
				num( this, name.toLowerCase() )
					+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
					+ num(this, 'padding' + torl) + num(this, 'padding' + borr);
		
		return val + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
	};
});

// Create scrollLeft and scrollTop methods
$.each( ['Left', 'Top'], function(i, name) {
	$.fn[ 'scroll' + name ] = function(val) {
		if (!this[0]) return;
		
		return val != undefined ?
		
			// Set the scroll offset
			this.each(function() {
				this == window || this == document ?
					window.scrollTo( 
						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
					) :
					this[ 'scroll' + name ] = val;
			}) :
			
			// Return the scroll offset
			this[0] == window || this[0] == document ?
				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
					$.boxModel && document.documentElement[ 'scroll' + name ] ||
					document.body[ 'scroll' + name ] :
				this[0][ 'scroll' + name ];
	};
});

$.fn.extend({
	position: function() {
		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
		
		if (elem) {
			// Get *real* offsetParent
			offsetParent = this.offsetParent();
			
			// Get correct offsets
			offset       = this.offset();
			parentOffset = offsetParent.offset();
			
			// Subtract element margins
			offset.top  -= num(elem, 'marginTop');
			offset.left -= num(elem, 'marginLeft');
			
			// Add offsetParent borders
			parentOffset.top  += num(offsetParent, 'borderTopWidth');
			parentOffset.left += num(offsetParent, 'borderLeftWidth');
			
			// Subtract the two offsets
			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}
		
		return results;
	},
	
	offsetParent: function() {
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

function num(el, prop) {
	return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
};

})(jQuery);
/*
 * jQuery clueTip plugin
 * Version 0.9.6  (02/02/2008)
 * @requires jQuery v1.1.1+
 * @requires Dimensions plugin 
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
(function($) { 
/*
 * @name clueTip
 * @type jQuery
 * @cat Plugins/tooltip
 * @return jQuery
 * @author Karl Swedberg
 *
 * @credit Inspired by Cody Lindley's jTip (http://www.codylindley.com)
 * @credit Thanks to the following people for their many and varied contributions:
      Shelane Enos, Glen Lipka, Hector Santos, Torben Schreiter, Dan G. Switzer, Jörn Zaefferer 
 * @credit Thanks to Jonathan Chaffer, as always, for help with the hard parts. :-)
 */

 /**
 * 
 * Displays a highly customizable tooltip when the user hovers (default) or clicks (optional) the matched element. 
 * By default, the clueTip plugin loads a page indicated by the "rel" attribute via ajax and displays its contents.
 * If a "title" attribute is specified, its value is used as the clueTip's heading.
 * The attribute to be used for both the body and the heading of the clueTip is user-configurable. 
 * Optionally, the clueTip's body can display content from an element on the same page.
 * * Just indicate the element's id (e.g. "#some-id") in the rel attribute.
 * Optionally, the clueTip's body can display content from the title attribute, when a delimiter is indicated. 
 * * The string before the first instance of the delimiter is set as the clueTip's heading.
 * * All subsequent strings are wrapped in separate DIVs and placed in the clueTip's body.
 * The clueTip plugin allows for many, many more options. Pleasee see the examples and the option descriptions below...
 * 
 * 
 * @example $('#tip).cluetip();
 * @desc This is the most basic clueTip. It displays a 275px-wide clueTip on mouseover of the element with an ID of "tip." On mouseout of the element, the clueTip is hidden.
 *
 *
 * @example $('a.clue').cluetip({
 *  hoverClass: 'highlight',
 *  sticky: true,
 *  closePosition: 'bottom',
 *  closeText: '<img src="cross.png" alt="close" />',
 *  truncate: 60,
 *  ajaxSettings: {
 *    type: 'POST'
 *  }
 * });
 * @desc Displays a clueTip on mouseover of all <a> elements with class="clue". The hovered element gets a class of "highlight" added to it (so that it can be styled appropriately. This is esp. useful for non-anchor elements.). The clueTip is "sticky," which means that it will not be hidden until the user either clicks on its "close" text/graphic or displays another clueTip. The "close" text/graphic is set to diplay at the bottom of the clueTip (default is top) and display an image rather than the default "Close" text. Moreover, the body of the clueTip is truncated to the first 60 characters, which are followed by an ellipsis (...). Finally, the clueTip retrieves the content using POST rather than the $.ajax method's default "GET."
 * 
 * More examples can be found at http://plugins.learningjquery.com/cluetip/demo/
 * 
 * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
 */

  var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $dropShadow, imgCount;
  $.fn.cluetip = function(options) {

    var opts = $.extend({},$.fn.cluetip.defaults, options);

    if (options && options.ajaxSettings) {
      $.extend(opts.ajaxSettings, options.ajaxSettings);
      delete options.ajaxSettings;
    }
    
    if (options && options.hoverIntent) {
      $.extend(opts.hoverIntent, options.hoverIntent);
      delete options.hoverIntent;
    }    

    if (options && options.fx) {
      $.extend(opts.fx, options.fx);
      delete options.fx;
    }
    
    return this.each(function(index) {
      // start out with no contents (for ajax activation)
      var cluetipContents = false;
      var cluezIndex = parseInt(opts.cluezIndex, 10)-1;
      var isActive = false, closeOnDelay = 0;

      // create the cluetip divs
      if (!$cluetip) {
        $cluetipInner = $('<div id="cluetip-inner"></div>');
        $cluetipTitle = $('<h3 id="cluetip-title"></h3>');        
        $cluetipOuter = $('<div id="cluetip-outer"></div>').append($cluetipInner).prepend($cluetipTitle);
        $cluetip = $('<div id="cluetip"></div>').css({zIndex: opts.cluezIndex})
        .append($cluetipOuter).append('<div id="cluetip-extra"></div>')[insertionType](insertionElement).hide();
        $('<div id="cluetip-waitimage"></div>').css({position: 'absolute', zIndex: cluezIndex-1})
        .insertBefore('#cluetip').hide();
        $cluetip.css({position: 'absolute', zIndex: cluezIndex});
        $cluetipOuter.css({position: 'relative', zIndex: cluezIndex+1});
        $cluetipArrows = $('<div id="cluetip-arrows" class="cluetip-arrows"></div>').css({zIndex: cluezIndex+1}).appendTo('#cluetip');
      }
      var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
      if (!$dropShadow) {
        $dropShadow = $([]);
        for (var i=0; i < dropShadowSteps; i++) {
          $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-i-1, opacity:.1, top: 1+i, left: 1+i}));
        };
        $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
        .prependTo($cluetip);
      }
      var $this = $(this);
      var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
      if (!tipAttribute && !opts.splitTitle) return true;
      // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip
      if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
      var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
      // vertical measurement variables
      var tipHeight, wHeight;
      var defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
      var sTop, linkTop, posY, tipY, mouseY, baseline;
      // horizontal measurement variables
      var tipInnerWidth = isNaN(parseInt(opts.width, 10)) ? 275 : parseInt(opts.width, 10);
      var tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'))||0) + (parseInt($cluetip.css('paddingRight'))||0) + dropShadowSteps;
      var linkWidth = this.offsetWidth;
      var linkLeft, posX, tipX, mouseX, winWidth;
            
      // parse the title
      var tipParts;
      var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
      if (opts.splitTitle) {
        if(tipTitle == undefined) {tipTitle = '';}
        tipParts = tipTitle.split(opts.splitTitle);
        tipTitle = tipParts.shift();
      }
      var localContent;
      

/***************************************      
* ACTIVATION
****************************************/
    
//activate clueTip
    var activate = function(event) {
      if (!opts.onActivate($this)) {
        return false;
      }
      isActive = true;
      $cluetip.removeClass().css({width: tipInnerWidth});
      if (tipAttribute == $this.attr('href')) {
        $this.css('cursor', opts.cursor);
      }
      $this.attr('title','');
      if (opts.hoverClass) {
        $this.addClass(opts.hoverClass);
      }
      linkTop = posY = $this.offset().top;
      linkLeft = $this.offset().left;
      mouseX = event.pageX;
      mouseY = event.pageY;
      if ($this[0].tagName.toLowerCase() != 'area') {
        sTop = $(document).scrollTop();
        winWidth = $(window).width();
      }
// position clueTip horizontally
      if (opts.positionBy == 'fixed') {
        posX = linkWidth + linkLeft + lOffset;
        $cluetip.css({left: posX});
      } else {
        posX = (linkWidth > linkLeft && linkLeft > tipWidth)
          || linkLeft + linkWidth + tipWidth + lOffset > winWidth 
          ? linkLeft - tipWidth - lOffset 
          : linkWidth + linkLeft + lOffset;
        if ($this[0].tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
          if (mouseX + 20 + tipWidth > winWidth) {  
            $cluetip.addClass(' cluetip-' + ctClass);
            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) :  mouseX - (tipWidth/2);
          } else {
            posX = mouseX + lOffset;
          }
        }
        var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
        $cluetip.css({left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0)});
      }
        wHeight = $(window).height();

/***************************************
* load the title attribute only (or user-selected attribute). 
* clueTip title is the string before the first delimiter
* subsequent delimiters place clueTip body text on separate lines
***************************************/
      if (tipParts) {
        var tpl = tipParts.length;
        for (var i=0; i < tpl; i++){
          if (i == 0) {
            $cluetipInner.html(tipParts[i]);
          } else { 
            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
          }            
        };
        cluetipShow(pY);
      }
/***************************************
* load external file via ajax          
***************************************/
      else if (!opts.local && tipAttribute.indexOf('#') != 0) {
        if (cluetipContents && opts.ajaxCache) {
          $cluetipInner.html(cluetipContents);
          cluetipShow(pY);
        }
        else {
          var ajaxSettings = opts.ajaxSettings;
          ajaxSettings.url = tipAttribute;
          ajaxSettings.beforeSend = function() {
            $cluetipOuter.children().empty();
            if (opts.waitImage) {
              $('#cluetip-waitimage')
              .css({top: mouseY+20, left: mouseX+20})
              .show();
            }
          };
         ajaxSettings.error = function() {
            if (isActive) {
              $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
            }
          };
          ajaxSettings.success = function(data) {
            cluetipContents = opts.ajaxProcess(data);
            if (isActive) {
              $cluetipInner.html(cluetipContents);
            }
          };
          ajaxSettings.complete = function() {
          	imgCount = $('#cluetip-inner img').length;
        		if (imgCount) {
        		  $('#cluetip-inner img').load( function(){
          			imgCount--;
          			if (imgCount<1) {
          				$('#cluetip-waitimage').hide();
          			  if (isActive) cluetipShow(pY);
          			}
        		  }); 
        		} else {
      				$('#cluetip-waitimage').hide();
        		  if (isActive) cluetipShow(pY);    
        		} 
          };
          $.ajax(ajaxSettings);
        }

/***************************************
* load an element from the same page
***************************************/
      } else if (opts.local){
        var $localContent = $(tipAttribute + ':first');
        var localCluetip = $.fn.wrapInner ? $localContent.wrapInner('<div></div>').children().clone(true) : $localContent.html();
        $.fn.wrapInner ? $cluetipInner.empty().append(localCluetip) : $cluetipInner.html(localCluetip);
        cluetipShow(pY);
      }
    };

// get dimensions and options for cluetip and prepare it to be shown
    var cluetipShow = function(bpY) {
      $cluetip.addClass('cluetip-' + ctClass);
      
      if (opts.truncate) { 
        var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
        $cluetipInner.html($truncloaded);
      }
      function doNothing() {}; //empty function
      tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
      if (opts.sticky) {
        var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
        (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
        $closeLink.click(function() {
          cluetipClose();
          return false;
        });
        if (opts.mouseOutClose) {
          if ($.fn.hoverIntent && opts.hoverIntent) { 
            $cluetip.hoverIntent({
              over: doNothing, 
              timeout: opts.hoverIntent.timeout,  
              out: function() { $closeLink.trigger('click'); }
            });
          } else {
            $cluetip.hover(doNothing, 
            function() {$closeLink.trigger('click'); });
          }
        } else {
          $cluetip.unbind('mouseout');
        }
      }
// now that content is loaded, finish the positioning 
      var direction = '';
      $cluetipOuter.css({overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
      tipHeight = defHeight == 'auto' ? $cluetip.outerHeight() : parseInt(defHeight,10);   
      tipY = posY;
      baseline = sTop + wHeight;
      if (opts.positionBy == 'fixed') {
        tipY = posY - opts.dropShadowSteps + tOffset;
      } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
        if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) { 
          tipY = mouseY - tipHeight - tOffset;
          direction = 'top';
        } else { 
          tipY = mouseY + tOffset;
          direction = 'bottom';
        }
      } else if ( posY + tipHeight + tOffset > baseline ) {
        tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
      } else if ($this.css('display') == 'block' || $this[0].tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
        tipY = bpY - tOffset;
      } else {
        tipY = posY - opts.dropShadowSteps;
      }
      if (direction == '') {
        posX < linkLeft ? direction = 'left' : direction = 'right';
      }
      $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
      if (opts.arrows) { // set up arrow positioning to align with element
        var bgY = (posY - tipY - opts.dropShadowSteps);
        $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
      } else {
        $cluetipArrows.hide();
      }

// (first hide, then) ***SHOW THE CLUETIP***
      $dropShadow.hide();
      $cluetip.hide()[opts.fx.open](opts.fx.open != 'show' && opts.fx.openSpeed);
      if (opts.dropShadow) $dropShadow.css({height: tipHeight, width: tipInnerWidth}).show();
      if ($.fn.bgiframe) { $cluetip.bgiframe(); }
      // trigger the optional onShow function
      if (opts.delayedClose > 0) {
        closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
      }

      opts.onShow($cluetip, $cluetipInner);
      
    };

/***************************************
   =INACTIVATION
-------------------------------------- */
    var inactivate = function() {
      isActive = false;
      $('#cluetip-waitimage').hide();
      if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
        cluetipClose();
clearTimeout(closeOnDelay);        
      };
      if (opts.hoverClass) {
        $this.removeClass(opts.hoverClass);
      }
      $('.cluetip-clicked').removeClass('cluetip-clicked');
    };
// close cluetip and reset some things
    var cluetipClose = function() {
      $cluetipOuter 
      .parent().hide().removeClass().end()
      .children().empty();
      if (tipTitle) {
        $this.attr('title', tipTitle);
      }
      $this.css('cursor','');
      if (opts.arrows) $cluetipArrows.css({top: ''});
    };

/***************************************
   =BIND EVENTS
-------------------------------------- */
  // activate by click
      if ( (/click|toggle/).test(opts.activation) ) {
        $this.click(function(event) {
          if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
            activate(event);
            $('.cluetip-clicked').removeClass('cluetip-clicked');
            $this.addClass('cluetip-clicked');

          } else {
            inactivate(event);

          }
          this.blur();
          return false;
        });
  // activate by focus; inactivate by blur    
      } else if (opts.activation == 'focus') {
        $this.focus(function(event) {
          activate(event);
        });
        $this.blur(function(event) {
          inactivate(event);
        });
  // activate by hover
    // clicking is returned false if cluetip url is same as href url
      } else {
        $this.click(function() {
          if ($this.attr('href') && $this.attr('href') == tipAttribute && !opts.clickThrough) {
            return false;
          }
        });
        //set up mouse tracking
        var mouseTracks = function(evt) {
          if (opts.tracking == true) {
            var trackX = posX - evt.pageX;
            var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
            $this.mousemove(function(evt) {
              $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
            });
          }
        };
        if ($.fn.hoverIntent && opts.hoverIntent) {
          $this.mouseover(function() {$this.attr('title',''); })
          .hoverIntent({
            sensitivity: opts.hoverIntent.sensitivity,
            interval: opts.hoverIntent.interval,  
            over: function(event) {
              activate(event);
              mouseTracks(event);
            }, 
            timeout: opts.hoverIntent.timeout,  
            out: function(event) {inactivate(event); $this.unbind('mousemove');}
          });           
        } else {
          $this.hover(function(event) {
            activate(event);
            mouseTracks(event);
          }, function(event) {
            inactivate(event);
            $this.unbind('mousemove');
          });
        }
      }
    });
  };
  
/*
 * options for clueTip
 *
 * each one can be explicitly overridden by changing its value. 
 * for example: $.fn.cluetip.defaults.width = 200; 
 * would change the default width for all clueTips to 200. 
 *
 * each one can also be overridden by passing an options map to the cluetip method.
 * for example: $('a.example').cluetip({width: 200}); 
 * would change the default width to 200 for clueTips invoked by a link with class of "example"
 *
 */
  
  $.fn.cluetip.defaults = {  // set up default options
    width:            275,      // The width of the clueTip
    height:           'auto',   // The height of the clueTip
    cluezIndex:       999999,       // Sets the z-index style property of the clueTip
    positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
    topOffset:        15,       // Number of px to offset clueTip from top of invoking element
    leftOffset:       15,       // Number of px to offset clueTip from left of invoking element
    local:            false,    // Whether to use content from the same page for the clueTip's body
    hideLocal:        true,     // If local option is set to true, this determines whether local content
                                // to be shown in clueTip should be hidden at its original location
    attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
    titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
    splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
                                // within the clueTip body. more info below [6]
    showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
    cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
    hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
    waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
    cursor:           'help',
    arrows:           false,    // if true, displays arrow on appropriate side of clueTip
    dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
    dropShadowSteps:  6,        // adjusts the size of the drop shadow
    sticky:           false,    // keep visible until manually closed
    mouseOutClose:    false,    // close when clueTip is moused out
    activation:       'hover',  // set to 'click' to force user to click to show clueTip
                                // set to 'focus' to show on focus of a form element and hide on blur
    clickThrough:     false,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
                                // even if href and tipAttribute are equal
    tracking:         false,    // if true, clueTip will track mouse movement (experimental)
    delayedClose:     0,        // close clueTip on a timed delay (experimental)
    closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
    closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
    truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs

    // effect and speed for opening clueTips
    fx: {             
                      open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
                      openSpeed:  ''
    },     

    // settings for when hoverIntent plugin is used             
    hoverIntent: {    
                      sensitivity:  3,
              			  interval:     50,
              			  timeout:      0
    },

    // function to run just before clueTip is shown.           
    onActivate:       function(e) {return true;},

    // function to run just after clueTip is shown.
    onShow:           function(ct, c){},
    
    // whether to cache results of ajax request to avoid unnecessary hits to server    
    ajaxCache:        true,  

    // process data retrieved via xhr before it's displayed
    ajaxProcess:      function(data) {
                        data = data.replace(/<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g, '').replace(/<(link|title)(.|\s)*?\/(link|title)>/g,'');
                        return data;
    },                

    // can pass in standard $.ajax() parameters, not including error, complete, success, and url
    ajaxSettings: {   
                      dataType: 'html'
    }
  };


/*
 * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
 *
 * @example $.cluetip.setup({
 *   insertionType: 'prependTo',
 *   insertionElement: '#container'
 * });
 * 
 * @property
 * @name $.cluetip.setup
 * @type Map
 * @cat Plugins/tooltip
 * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
 * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
 *
 */
   
  var insertionType = 'appendTo', insertionElement = 'body';
  $.cluetip = {};
  $.cluetip.setup = function(options) {
    if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
      insertionType = options.insertionType;
    }
    if (options && options.insertionElement) {
      insertionElement = options.insertionElement;
    }
  };
  
})(jQuery);
/*
 * SimpleModal 1.1.1 - jQuery Plugin
 * http://www.ericmmartin.com/projects/simplemodal/
 * http://plugins.jquery.com/project/SimpleModal
 * http://code.google.com/p/simplemodal/
 *
 * Copyright (c) 2007 Eric Martin - http://ericmmartin.com
 *
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Revision: $Id: jquery.simplemodal.js 93 2008-01-15 16:14:20Z emartin24 $
 *
 */

/**
 * SimpleModal is a lightweight jQuery plugin that provides a simple
 * interface to create a modal dialog.
 *
 * The goal of SimpleModal is to provide developers with a cross-browser 
 * overlay and container that will be populated with data provided to
 * SimpleModal.
 *
 * There are two ways to call SimpleModal:
 * 1) As a chained function on a jQuery object, like $('#myDiv').modal();.
 * This call would place the DOM object, #myDiv, inside a modal dialog.
 * Chaining requires a jQuery object. An optional options object can be
 * passed as a parameter.
 *
 * @example $('<div>my data</div>').modal({options});
 * @example $('#myDiv').modal({options});
 * @example jQueryObject.modal({options});
 *
 * 2) As a stand-alone function, like $.modal(data). The data parameter
 * is required and an optional options object can be passed as a second
 * parameter. This method provides more flexibility in the types of data 
 * that are allowed. The data could be a DOM object, a jQuery object, HTML
 * or a string.
 * 
 * @example $.modal('<div>my data</div>', {options});
 * @example $.modal('my data', {options});
 * @example $.modal($('#myDiv'), {options});
 * @example $.modal(jQueryObject, {options});
 * @example $.modal(document.getElementById('myDiv'), {options}); 
 * 
 * A SimpleModal call can contain multiple elements, but only one modal 
 * dialog can be created at a time. Which means that all of the matched
 * elements will be displayed within the modal container.
 * 
 * SimpleModal internally sets the CSS needed to display the modal dialog
 * properly in all browsers, yet provides the developer with the flexibility
 * to easily control the look and feel. The styling for SimpleModal can be 
 * done through external stylesheets, or through SimpleModal, using the
 * overlayCss and/or containerCss options.
 *
 * SimpleModal has been tested in the following browsers:
 * - IE 6, 7
 * - Firefox 2
 * - Opera 9
 * - Safari 3
 *
 * @name SimpleModal
 * @type jQuery
 * @requires jQuery v1.1.2
 * @cat Plugins/Windows and Overlays
 * @author Eric Martin (http://ericmmartin.com)
 * @version 1.1.1
 */
(function ($) {
	/*
	 * Stand-alone function to create a modal dialog.
	 * 
	 * @param {string, object} data A string, jQuery object or DOM object
	 * @param {object} [options] An optional object containing options overrides
	 */
	$.modal = function (data, options) {
		return $.modal.impl.init(data, options);
	};

	/*
	 * Stand-alone close function to close the modal dialog
	 */
	$.modal.close = function () {
		// call close with the external parameter set to true
		$.modal.impl.close(true);
	};

	/*
	 * Chained function to create a modal dialog.
	 * 
	 * @param {object} [options] An optional object containing options overrides
	 */
	$.fn.modal = function (options) {
		return $.modal.impl.init(this, options);
	};

	/*
	 * SimpleModal default options
	 * 
	 * overlay: (Number:50) The overlay div opacity value, from 0 - 100
	 * overlayId: (String:'modalOverlay') The DOM element id for the overlay div
	 * overlayCss: (Object:{}) The CSS styling for the overlay div
	 * containerId: (String:'modalContainer') The DOM element id for the container div
	 * containerCss: (Object:{}) The CSS styling for the container div
	 * close: (Boolean:true) Show the default window close icon? Uses CSS class modalCloseImg
	 * closeTitle: (String:'Close') The title value of the default close link. Depends on close
	 * closeClass: (String:'modalClose') The CSS class used to bind to the close event
	 * persist: (Boolean:false) Persist the data across modal calls? Only used for existing
	            DOM elements. If true, the data will be maintained across modal calls, if false,
				the data will be reverted to its original state.
	 * onOpen: (Function:null) The callback function used in place of SimpleModal's open
	 * onShow: (Function:null) The callback function used after the modal dialog has opened
	 * onClose: (Function:null) The callback function used in place of SimpleModal's close
	 */
	$.modal.defaults = {
		overlay: 50,
		overlayId: 'modalOverlay',
		overlayCss: {},
		containerId: 'modalContainer',
		containerCss: {},
		close: true,
		closeTitle: 'Close',
		closeClass: 'modalClose',
		persist: false,
		onOpen: null,
		onShow: null,
		onClose: null
	};

	/*
	 * Main modal object
	 */
	$.modal.impl = {
		/*
		 * Modal dialog options
		 */
		opts: null,
		/*
		 * Contains the modal dialog elements and is the object passed 
		 * back to the callback (onOpen, onShow, onClose) functions
		 */
		dialog: {},
		/*
		 * Initialize the modal dialog
		 */
		init: function (data, options) {
			// don't allow multiple calls
			if (this.dialog.data) {
				return false;
			}

			// merge defaults and user options
			this.opts = $.extend({}, $.modal.defaults, options);

			// determine how to handle the data based on its type
			if (typeof data == 'object') {
				// convert DOM object to a jQuery object
				data = data instanceof jQuery ? data : $(data);

				// if the object came from the DOM, keep track of its parent
				if (data.parent().parent().size() > 0) {
					this.dialog.parentNode = data.parent();

					// persist changes? if not, make a clone of the element
					if (!this.opts.persist) {
						this.dialog.original = data.clone(true);
					}
				}
			}
			else if (typeof data == 'string' || typeof data == 'number') {
				// just insert the data as innerHTML
				data = $('<div>').html(data);
			}
			else {
				// unsupported data type!
				if (console) {
					console.log('SimpleModal Error: Unsupported data type: ' + typeof data);
				}
				return false;
			}
			this.dialog.data = data.addClass('modalData');
			data = null;

			// create the modal overlay, container and, if necessary, iframe
			this.create();

			// display the modal dialog
			this.open();

			// useful for adding events/manipulating data in the modal dialog
			if ($.isFunction(this.opts.onShow)) {
				this.opts.onShow.apply(this, [this.dialog]);
			}

			// don't break the chain =)
			return this;
		},
		/*
		 * Create and add the modal overlay and container to the page
		 */
		create: function () {
			// create the overlay
			this.dialog.overlay = $('<div>')
				.attr('id', this.opts.overlayId)
				.addClass('modalOverlay')
				.css($.extend(this.opts.overlayCss, {
					opacity: this.opts.overlay / 100,
					height: '100%',
					width: '100%',
					position: 'fixed',
					left: 0,
					top: 0,
					zIndex: 3000
				}))
				.hide()
				.appendTo('body');

			// create the container
			this.dialog.container = $('<div>')
				.attr('id', this.opts.containerId)
				.addClass('modalContainer')
				.css($.extend(this.opts.containerCss, {
					position: 'fixed', 
					zIndex: 3100
				}))
				.append(this.opts.close 
					? '<a class="modalCloseImg ' 
						+ this.opts.closeClass 
						+ '" title="' 
						+ this.opts.closeTitle + '"></a>'
					: '')
				.hide()
				.appendTo('body');

			// fix issues with IE and create an iframe
			if ($.browser.msie && ($.browser.version < 7)) {
				this.fixIE();
			}

			// hide the data and add it to the container
			this.dialog.container.append(this.dialog.data.hide());
		},
		/*
		 * Bind events
		 */
		bindEvents: function () {
			var modal = this;

			// bind the close event to any element with the closeClass class
			$('.' + this.opts.closeClass).click(function (e) {
				e.preventDefault();
				modal.close();
			});
		},
		/*
		 * Unbind events
		 */
		unbindEvents: function () {
			// remove the close event
			$('.' + this.opts.closeClass).unbind('click');
		},
		/*
		 * Fix issues in IE 6
		 */
		fixIE: function () {
			var wHeight = $(document.body).height() + 'px';
			var wWidth = $(document.body).width() + 'px';

			// position hacks
			this.dialog.overlay.css({position: 'absolute', height: wHeight, width: wWidth});
			this.dialog.container.css({position: 'absolute'});

			// add an iframe to prevent select options from bleeding through
			this.dialog.iframe = $('<iframe src="javascript:false;">')
				.css($.extend(this.opts.iframeCss, {
					opacity: 0, 
					position: 'absolute',
					height: wHeight,
					width: wWidth,
					zIndex: 1000,
					width: '100%',
					top: 0,
					left: 0
				}))
				.hide()
				.appendTo('body');
		},
		/*
		 * Open the modal dialog elements
		 * - Note: If you use the onOpen callback, you must "show" the 
		 *         overlay and container elements manually 
		 *         (the iframe will be handled by SimpleModal)
		 */
		open: function () {
			// display the iframe
			if (this.dialog.iframe) {
				this.dialog.iframe.show();
			}

			if ($.isFunction(this.opts.onOpen)) {
				// execute the onOpen callback 
				this.opts.onOpen.apply(this, [this.dialog]);
			}
			else {
				// display the remaining elements
				this.dialog.overlay.show();
				this.dialog.container.show();
				this.dialog.data.show();
			}

			// bind default events
			this.bindEvents();
		},
		/*
		 * Close the modal dialog
		 * - Note: If you use an onClose callback, you must remove the 
		 *         overlay, container and iframe elements manually
		 *
		 * @param {boolean} external Indicates whether the call to this
		 *     function was internal or external. If it was external, the
		 *     onClose callback will be ignored
		 */
		close: function (external) {
			// prevent close when dialog does not exist
			if (!this.dialog.data) {
				return false;
			}

			if ($.isFunction(this.opts.onClose) && !external) {
				// execute the onClose callback
				this.opts.onClose.apply(this, [this.dialog]);
			}
			else {
				// if the data came from the DOM, put it back
				if (this.dialog.parentNode) {
					// save changes to the data?
					if (this.opts.persist) {
						// insert the (possibly) modified data back into the DOM
						this.dialog.data.hide().appendTo(this.dialog.parentNode);
					}
					else {
						// remove the current and insert the original, 
						// unmodified data back into the DOM
						this.dialog.data.remove();
						this.dialog.original.appendTo(this.dialog.parentNode);
					}
				}
				else {
					// otherwise, remove it
					this.dialog.data.remove();
				}

				// remove the remaining elements
				this.dialog.container.remove();
				this.dialog.overlay.remove();
				if (this.dialog.iframe) {
					this.dialog.iframe.remove();
				}

				// reset the dialog object
				this.dialog = {};
			}

			// remove the default events
			this.unbindEvents();
		}
	};
})(jQuery);
/**
 * @author alexander.farkas
 * @version 1.01 
 */
(function($){
    $.extend({
        manageAjax: function(o){
            o = $.extend({
                manageType: 'normal',
                maxReq: 0,
                blockSameRequest: false,
				global: true
            }, o);
            return new $.ajaxManager(o);
        },
        ajaxManager: function(o){
            this.opt = o;
            this.queue = [];
        }
    });
    $.extend($.ajaxManager.prototype, {
        add: function(o){
            var quLen = this.queue.length, s = this.opt, q = this.queue, self = this, i, j;
            var cD = (o.data && typeof o.data != "string") ? $.param(o.data) : o.data;
            if (s.blockSameRequest) {
                var toPrevent = false;
                for (i = 0; i < quLen; i++) {
                    if (q[i] && q[i].data === cD && q[i].url === o.url && q[i].type === o.type) {
                        toPrevent = true;
                        break;
                    }
                }
                if (toPrevent) {
                    return false;
                }
            }
            q[quLen] = {
                fnError: o.error,
                fnSuccess: o.success,
                fnComplete: o.complete,
                fnAbort: o.abort,
                error: [],
                success: [],
                complete: [],
                done: false,
                queued: false,
                data: cD,
                url: o.url,
                type: o.type,
                xhr: null
            };
            
            o.error = function(){
                if (q[quLen]) {
                    q[quLen].error = arguments;
                }
            };
            o.success = function(){
                if (q[quLen]) {
                    q[quLen].success = arguments;
                }
            };
            o.abort = function(){
                if (q[quLen]) {
                    q[quLen].abort = arguments;
                }
            };
            function startCallbacks(num){
                if (q[num].fnError) {
                    q[num].fnError.apply($, q[num].error);
                }
                if (q[num].fnSuccess) {
                    q[num].fnSuccess.apply($, q[num].success);
                }
                if (q[num].fnComplete) {
                    q[num].fnComplete.apply($, q[num].complete);
                }
                self.abort(num, true);
            }
            
            o.complete = function(){
                if (!q[quLen]) {
                    return;
                }
                q[quLen].complete = arguments;
                q[quLen].done = true;
                switch (s.manageType) {
                    case 'sync':
                        if (quLen === 0 || !q[quLen - 1]) {
                            var curQLen = q.length;
                            for (i = quLen; i < curQLen; i++) {
                                if (q[i]) {
                                    if (q[i].done) {
                                        startCallbacks(i);
                                    }
                                    else {
                                        break;
                                    }
                                }
                                
                            }
                        }
                        break;
                    case 'queue':
                        if (quLen === 0 || !q[quLen - 1]) {
                            var curQLen = q.length;
                            for (i = 0, j = 0; i < curQLen; i++) {
                                if (q[i] && q[i].queued) {
                                    q[i].xhr = jQuery.ajax(q[i].xhr);
                                    q[i].queued = false;
                                    break;
                                }
                            }
                        }
                        startCallbacks(quLen);
                        break;
                    case 'abortOld':
                        startCallbacks(quLen);
                        for (i = quLen; i >= 0; i--) {
                            if (q[i]) {
                                self.abort(i);
                            }
                        }
                        break;
                    default:
                        startCallbacks(quLen);
                        break;
                }
            };
            
            if (s.maxReq) {
                if (s.manageType != 'queue') {
                    for (i = quLen, j = 0; i >= 0; i--) {
                        if (j >= s.maxReq) {
                            this.abort(i);
                        }
                        if (q[i]) {
                            j++;
                        }
                    }
                }
                else {
                    for (i = 0, j = 0; i <= quLen && !q[quLen].queued; i++) {
                        if (q[i] && !q[i].queued) 
                            j++;
                        if (j > s.maxReq) 
                            q[quLen].queued = true;
                    }
                }
            }
            q[quLen].xhr = (q[quLen].queued) ? o : jQuery.ajax(o);
            return quLen;
        },
        cleanUp: function(){
            this.queue = [];
        },
        abort: function(num, completed){
            var qLen = this.queue.length, s = this.opt, q = this.queue, self = this, i;
            function del(num){
                if (!q[num]) {
                    return;
                }
                (!completed && q[num].fnAbort) && q[num].fnAbort.apply($, [num]);
                if (!q[num]) {
                    return;
                }
                if (q[num].xhr) {
                    if (typeof q[num].xhr.abort != 'undefined') {
                        q[num].xhr.abort();
                    }
                    if (typeof q[num].xhr.close != 'undefined') {
                        q[num].xhr.close();
                    }
                    q[num].xhr = null;
                }
				// Handle the global AJAX counter
			
				if ( s.global && $.active && ! --$.active){
					$.event.trigger( "ajaxStop" );
				}
                q[num] = null;
            }
            if (!num && num !== 0) {
                for (i = 0; i < qLen; i++) {
                    del(i);
                }
                this.cleanUp();
            }
            else {
                del(num);
                var allowCleaning = true;
                for (i = qLen; i >= 0; i--) {
                    if (q[i]) {
                        allowCleaning = false;
                        break;
                    }
                }
                if (allowCleaning) {
                    this.cleanUp();
                }
            }
        }
    });
})(jQuery);

/*
 * jQuery UI 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;jQuery.ui || (function($) {

var _remove = $.fn.remove,
	isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);

//Helper functions and ui object
$.ui = {
	version: "1.7.2",

	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
	plugin: {
		add: function(module, option, set) {
			var proto = $.ui[module].prototype;
			for(var i in set) {
				proto.plugins[i] = proto.plugins[i] || [];
				proto.plugins[i].push([option, set[i]]);
			}
		},
		call: function(instance, name, args) {
			var set = instance.plugins[name];
			if(!set || !instance.element[0].parentNode) { return; }

			for (var i = 0; i < set.length; i++) {
				if (instance.options[set[i][0]]) {
					set[i][1].apply(instance.element, args);
				}
			}
		}
	},

	contains: function(a, b) {
		return document.compareDocumentPosition
			? a.compareDocumentPosition(b) & 16
			: a !== b && a.contains(b);
	},

	hasScroll: function(el, a) {

		//If overflow is hidden, the element might have extra content, but the user wants to hide it
		if ($(el).css('overflow') == 'hidden') { return false; }

		var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
			has = false;

		if (el[scroll] > 0) { return true; }

		// TODO: determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[scroll] = 1;
		has = (el[scroll] > 0);
		el[scroll] = 0;
		return has;
	},

	isOverAxis: function(x, reference, size) {
		//Determines when x coordinate is over "b" element axis
		return (x > reference) && (x < (reference + size));
	},

	isOver: function(y, x, top, left, height, width) {
		//Determines when x, y coordinates is over "b" element
		return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
	},

	keyCode: {
		BACKSPACE: 8,
		CAPS_LOCK: 20,
		COMMA: 188,
		CONTROL: 17,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		INSERT: 45,
		LEFT: 37,
		NUMPAD_ADD: 107,
		NUMPAD_DECIMAL: 110,
		NUMPAD_DIVIDE: 111,
		NUMPAD_ENTER: 108,
		NUMPAD_MULTIPLY: 106,
		NUMPAD_SUBTRACT: 109,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SHIFT: 16,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
};

// WAI-ARIA normalization
if (isFF2) {
	var attr = $.attr,
		removeAttr = $.fn.removeAttr,
		ariaNS = "http://www.w3.org/2005/07/aaa",
		ariaState = /^aria-/,
		ariaRole = /^wairole:/;

	$.attr = function(elem, name, value) {
		var set = value !== undefined;

		return (name == 'role'
			? (set
				? attr.call(this, elem, name, "wairole:" + value)
				: (attr.apply(this, arguments) || "").replace(ariaRole, ""))
			: (ariaState.test(name)
				? (set
					? elem.setAttributeNS(ariaNS,
						name.replace(ariaState, "aaa:"), value)
					: attr.call(this, elem, name.replace(ariaState, "aaa:")))
				: attr.apply(this, arguments)));
	};

	$.fn.removeAttr = function(name) {
		return (ariaState.test(name)
			? this.each(function() {
				this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
			}) : removeAttr.call(this, name));
	};
}

//jQuery plugins
$.fn.extend({
	remove: function() {
		// Safari has a native remove event which actually removes DOM elements,
		// so we have to use triggerHandler instead of trigger (#3037).
		$("*", this).add(this).each(function() {
			$(this).triggerHandler("remove");
		});
		return _remove.apply(this, arguments );
	},

	enableSelection: function() {
		return this
			.attr('unselectable', 'off')
			.css('MozUserSelect', '')
			.unbind('selectstart.ui');
	},

	disableSelection: function() {
		return this
			.attr('unselectable', 'on')
			.css('MozUserSelect', 'none')
			.bind('selectstart.ui', function() { return false; });
	},

	scrollParent: function() {
		var scrollParent;
		if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		}

		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
	}
});


//Additional selectors
$.extend($.expr[':'], {
	data: function(elem, i, match) {
		return !!$.data(elem, match[3]);
	},

	focusable: function(element) {
		var nodeName = element.nodeName.toLowerCase(),
			tabIndex = $.attr(element, 'tabindex');
		return (/input|select|textarea|button|object/.test(nodeName)
			? !element.disabled
			: 'a' == nodeName || 'area' == nodeName
				? element.href || !isNaN(tabIndex)
				: !isNaN(tabIndex))
			// the element and all of its ancestors must be visible
			// the browser may report that the area is hidden
			&& !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
	},

	tabbable: function(element) {
		var tabIndex = $.attr(element, 'tabindex');
		return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
	}
});


// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
function getter(namespace, plugin, method, args) {
	function getMethods(type) {
		var methods = $[namespace][plugin][type] || [];
		return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
	}

	var methods = getMethods('getter');
	if (args.length == 1 && typeof args[0] == 'string') {
		methods = methods.concat(getMethods('getterSetter'));
	}
	return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
	var namespace = name.split(".")[0];
	name = name.split(".")[1];

	// create plugin method
	$.fn[name] = function(options) {
		var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);

		// prevent calls to internal methods
		if (isMethodCall && options.substring(0, 1) == '_') {
			return this;
		}

		// handle getter methods
		if (isMethodCall && getter(namespace, name, options, args)) {
			var instance = $.data(this[0], name);
			return (instance ? instance[options].apply(instance, args)
				: undefined);
		}

		// handle initialization and non-getter methods
		return this.each(function() {
			var instance = $.data(this, name);

			// constructor
			(!instance && !isMethodCall &&
				$.data(this, name, new $[namespace][name](this, options))._init());

			// method call
			(instance && isMethodCall && $.isFunction(instance[options]) &&
				instance[options].apply(instance, args));
		});
	};

	// create widget constructor
	$[namespace] = $[namespace] || {};
	$[namespace][name] = function(element, options) {
		var self = this;

		this.namespace = namespace;
		this.widgetName = name;
		this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
		this.widgetBaseClass = namespace + '-' + name;

		this.options = $.extend({},
			$.widget.defaults,
			$[namespace][name].defaults,
			$.metadata && $.metadata.get(element)[name],
			options);

		this.element = $(element)
			.bind('setData.' + name, function(event, key, value) {
				if (event.target == element) {
					return self._setData(key, value);
				}
			})
			.bind('getData.' + name, function(event, key) {
				if (event.target == element) {
					return self._getData(key);
				}
			})
			.bind('remove', function() {
				return self.destroy();
			});
	};

	// add widget prototype
	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);

	// TODO: merge getter and getterSetter properties from widget prototype
	// and plugin prototype
	$[namespace][name].getterSetter = 'option';
};

$.widget.prototype = {
	_init: function() {},
	destroy: function() {
		this.element.removeData(this.widgetName)
			.removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
			.removeAttr('aria-disabled');
	},

	option: function(key, value) {
		var options = key,
			self = this;

		if (typeof key == "string") {
			if (value === undefined) {
				return this._getData(key);
			}
			options = {};
			options[key] = value;
		}

		$.each(options, function(key, value) {
			self._setData(key, value);
		});
	},
	_getData: function(key) {
		return this.options[key];
	},
	_setData: function(key, value) {
		this.options[key] = value;

		if (key == 'disabled') {
			this.element
				[value ? 'addClass' : 'removeClass'](
					this.widgetBaseClass + '-disabled' + ' ' +
					this.namespace + '-state-disabled')
				.attr("aria-disabled", value);
		}
	},

	enable: function() {
		this._setData('disabled', false);
	},
	disable: function() {
		this._setData('disabled', true);
	},

	_trigger: function(type, event, data) {
		var callback = this.options[type],
			eventName = (type == this.widgetEventPrefix
				? type : this.widgetEventPrefix + type);

		event = $.Event(event);
		event.type = eventName;

		// copy original event properties over to the new event
		// this would happen if we could call $.event.fix instead of $.Event
		// but we don't have a way to force an event to be fixed multiple times
		if (event.originalEvent) {
			for (var i = $.event.props.length, prop; i;) {
				prop = $.event.props[--i];
				event[prop] = event.originalEvent[prop];
			}
		}

		this.element.trigger(event, data);

		return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
			|| event.isDefaultPrevented());
	}
};

$.widget.defaults = {
	disabled: false
};


/** Mouse Interaction Plugin **/

$.ui.mouse = {
	_mouseInit: function() {
		var self = this;

		this.element
			.bind('mousedown.'+this.widgetName, function(event) {
				return self._mouseDown(event);
			})
			.bind('click.'+this.widgetName, function(event) {
				if(self._preventClickEvent) {
					self._preventClickEvent = false;
					event.stopImmediatePropagation();
					return false;
				}
			});

		// Prevent text selection in IE
		if ($.browser.msie) {
			this._mouseUnselectable = this.element.attr('unselectable');
			this.element.attr('unselectable', 'on');
		}

		this.started = false;
	},

	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	_mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);

		// Restore text selection in IE
		($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
	},

	_mouseDown: function(event) {
		// don't let more than one widget handle mouseStart
		// TODO: figure out why we have to use originalEvent
		event.originalEvent = event.originalEvent || {};
		if (event.originalEvent.mouseHandled) { return; }

		// we may have missed mouseup (out of window)
		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var self = this,
			btnIsLeft = (event.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				self.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		// these delegates are required to keep context
		this._mouseMoveDelegate = function(event) {
			return self._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return self._mouseUp(event);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		// preventDefault() is used to prevent the selection of text here -
		// however, in Safari, this causes select boxes not to be selectable
		// anymore, so this fix is needed
		($.browser.safari || event.preventDefault());

		event.originalEvent.mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		// IE mouseup check - mouseup happened when mouse was out of window
		if ($.browser.msie && !event.button) {
			return this._mouseUp(event);
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		if (this._mouseStarted) {
			this._mouseStarted = false;
			this._preventClickEvent = (event.target == this._mouseDownEvent.target);
			this._mouseStop(event);
		}

		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(event) {
		return this.mouseDelayMet;
	},

	// These are placeholder methods, to be overriden by extending plugin
	_mouseStart: function(event) {},
	_mouseDrag: function(event) {},
	_mouseStop: function(event) {},
	_mouseCapture: function(event) { return true; }
};

$.ui.mouse.defaults = {
	cancel: null,
	distance: 1,
	delay: 0
};

})(jQuery);

/*
 * jQuery UI Draggable 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Draggables
 *
 * Depends:
 *	ui.core.js
 */
(function($) {

$.widget("ui.draggable", $.extend({}, $.ui.mouse, {

	_init: function() {

		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
			this.element[0].style.position = 'relative';

		(this.options.addClasses && this.element.addClass("ui-draggable"));
		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));

		this._mouseInit();

	},

	destroy: function() {
		if(!this.element.data('draggable')) return;
		this.element
			.removeData("draggable")
			.unbind(".draggable")
			.removeClass("ui-draggable"
				+ " ui-draggable-dragging"
				+ " ui-draggable-disabled");
		this._mouseDestroy();
	},

	_mouseCapture: function(event) {

		var o = this.options;

		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
			return false;

		//Quit if we're not on a valid handle
		this.handle = this._getHandle(event);
		if (!this.handle)
			return false;

		return true;

	},

	_mouseStart: function(event) {

		var o = this.options;

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		//Cache the helper size
		this._cacheHelperProportions();

		//If ddmanager is used for droppables, set the global draggable
		if($.ui.ddmanager)
			$.ui.ddmanager.current = this;

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Store the helper's css position
		this.cssPosition = this.helper.css("position");
		this.scrollParent = this.helper.scrollParent();

		//The element's absolute position on the page minus margins
		this.offset = this.element.offset();
		this.offset = {
			top: this.offset.top - this.margins.top,
			left: this.offset.left - this.margins.left
		};

		$.extend(this.offset, {
			click: { //Where the click happened, relative to the element
				left: event.pageX - this.offset.left,
				top: event.pageY - this.offset.top
			},
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
		});

		//Generate the original position
		this.originalPosition = this._generatePosition(event);
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
		if(o.cursorAt)
			this._adjustOffsetFromHelper(o.cursorAt);

		//Set a containment if given in the options
		if(o.containment)
			this._setContainment();

		//Call plugins and callbacks
		this._trigger("start", event);

		//Recache the helper size
		this._cacheHelperProportions();

		//Prepare the droppable offsets
		if ($.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(this, event);

		this.helper.addClass("ui-draggable-dragging");
		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
		return true;
	},

	_mouseDrag: function(event, noPropagation) {

		//Compute the helpers position
		this.position = this._generatePosition(event);
		this.positionAbs = this._convertPositionTo("absolute");

		//Call plugins and callbacks and use the resulting position if something is returned
		if (!noPropagation) {
			var ui = this._uiHash();
			this._trigger('drag', event, ui);
			this.position = ui.position;
		}

		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);

		return false;
	},

	_mouseStop: function(event) {

		//If we are using droppables, inform the manager about the drop
		var dropped = false;
		if ($.ui.ddmanager && !this.options.dropBehaviour)
			dropped = $.ui.ddmanager.drop(this, event);

		//if a drop comes from outside (a sortable)
		if(this.dropped) {
			dropped = this.dropped;
			this.dropped = false;
		}

		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
			var self = this;
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
				self._trigger("stop", event);
				self._clear();
			});
		} else {
			this._trigger("stop", event);
			this._clear();
		}

		return false;
	},

	_getHandle: function(event) {

		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
		$(this.options.handle, this.element)
			.find("*")
			.andSelf()
			.each(function() {
				if(this == event.target) handle = true;
			});

		return handle;

	},

	_createHelper: function(event) {

		var o = this.options;
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);

		if(!helper.parents('body').length)
			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));

		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
			helper.css("position", "absolute");

		return helper;

	},

	_adjustOffsetFromHelper: function(obj) {
		if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
		if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
		if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
	},

	_getParentOffset: function() {

		//Get the offsetParent and cache its position
		this.offsetParent = this.helper.offsetParent();
		var po = this.offsetParent.offset();

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
			po = { top: 0, left: 0 };

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
		};

	},

	_getRelativeOffset: function() {

		if(this.cssPosition == "relative") {
			var p = this.element.position();
			return {
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
			};
		} else {
			return { top: 0, left: 0 };
		}

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.element.css("marginLeft"),10) || 0),
			top: (parseInt(this.element.css("marginTop"),10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var o = this.options;
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
			0 - this.offset.relative.left - this.offset.parent.left,
			0 - this.offset.relative.top - this.offset.parent.top,
			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
		];

		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
			var ce = $(o.containment)[0]; if(!ce) return;
			var co = $(o.containment).offset();
			var over = ($(ce).css("overflow") != 'hidden');

			this.containment = [
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
			];
		} else if(o.containment.constructor == Array) {
			this.containment = o.containment;
		}

	},

	_convertPositionTo: function(d, pos) {

		if(!pos) pos = this.position;
		var mod = d == "absolute" ? 1 : -1;
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		return {
			top: (
				pos.top																	// The absolute mouse position
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
			),
			left: (
				pos.left																// The absolute mouse position
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
			)
		};

	},

	_generatePosition: function(event) {

		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		// This is another very weird special case that only happens for relative elements:
		// 1. If the css position is relative
		// 2. and the scroll parent is the document or similar to the offset parent
		// we have to refresh the relative offset during the scroll so there are no jumps
		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
			this.offset.relative = this._getRelativeOffset();
		}

		var pageX = event.pageX;
		var pageY = event.pageY;

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		if(this.originalPosition) { //If we are not dragging yet, we won't check for options

			if(this.containment) {
				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
			}

			if(o.grid) {
				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

		}

		return {
			top: (
				pageY																// The absolute mouse position
				- this.offset.click.top													// Click offset (relative to the element)
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
			),
			left: (
				pageX																// The absolute mouse position
				- this.offset.click.left												// Click offset (relative to the element)
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
			)
		};

	},

	_clear: function() {
		this.helper.removeClass("ui-draggable-dragging");
		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
		this.helper = null;
		this.cancelHelperRemoval = false;
	},

	// From now on bulk stuff - mainly helpers

	_trigger: function(type, event, ui) {
		ui = ui || this._uiHash();
		$.ui.plugin.call(this, type, [event, ui]);
		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
		return $.widget.prototype._trigger.call(this, type, event, ui);
	},

	plugins: {},

	_uiHash: function(event) {
		return {
			helper: this.helper,
			position: this.position,
			absolutePosition: this.positionAbs, //deprecated
			offset: this.positionAbs
		};
	}

}));

$.extend($.ui.draggable, {
	version: "1.7.2",
	eventPrefix: "drag",
	defaults: {
		addClasses: true,
		appendTo: "parent",
		axis: false,
		cancel: ":input,option",
		connectToSortable: false,
		containment: false,
		cursor: "auto",
		cursorAt: false,
		delay: 0,
		distance: 1,
		grid: false,
		handle: false,
		helper: "original",
		iframeFix: false,
		opacity: false,
		refreshPositions: false,
		revert: false,
		revertDuration: 500,
		scope: "default",
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		snap: false,
		snapMode: "both",
		snapTolerance: 20,
		stack: false,
		zIndex: false
	}
});

$.ui.plugin.add("draggable", "connectToSortable", {
	start: function(event, ui) {

		var inst = $(this).data("draggable"), o = inst.options,
			uiSortable = $.extend({}, ui, { item: inst.element });
		inst.sortables = [];
		$(o.connectToSortable).each(function() {
			var sortable = $.data(this, 'sortable');
			if (sortable && !sortable.options.disabled) {
				inst.sortables.push({
					instance: sortable,
					shouldRevert: sortable.options.revert
				});
				sortable._refreshItems();	//Do a one-time refresh at start to refresh the containerCache
				sortable._trigger("activate", event, uiSortable);
			}
		});

	},
	stop: function(event, ui) {

		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
		var inst = $(this).data("draggable"),
			uiSortable = $.extend({}, ui, { item: inst.element });

		$.each(inst.sortables, function() {
			if(this.instance.isOver) {

				this.instance.isOver = 0;

				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)

				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
				if(this.shouldRevert) this.instance.options.revert = true;

				//Trigger the stop of the sortable
				this.instance._mouseStop(event);

				this.instance.options.helper = this.instance.options._helper;

				//If the helper has been the original item, restore properties in the sortable
				if(inst.options.helper == 'original')
					this.instance.currentItem.css({ top: 'auto', left: 'auto' });

			} else {
				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
				this.instance._trigger("deactivate", event, uiSortable);
			}

		});

	},
	drag: function(event, ui) {

		var inst = $(this).data("draggable"), self = this;

		var checkPos = function(o) {
			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
			var itemHeight = o.height, itemWidth = o.width;
			var itemTop = o.top, itemLeft = o.left;

			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
		};

		$.each(inst.sortables, function(i) {
			
			//Copy over some variables to allow calling the sortable's native _intersectsWith
			this.instance.positionAbs = inst.positionAbs;
			this.instance.helperProportions = inst.helperProportions;
			this.instance.offset.click = inst.offset.click;
			
			if(this.instance._intersectsWith(this.instance.containerCache)) {

				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
				if(!this.instance.isOver) {

					this.instance.isOver = 1;
					//Now we fake the start of dragging for the sortable instance,
					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
					this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
					this.instance.options.helper = function() { return ui.helper[0]; };

					event.target = this.instance.currentItem[0];
					this.instance._mouseCapture(event, true);
					this.instance._mouseStart(event, true, true);

					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
					this.instance.offset.click.top = inst.offset.click.top;
					this.instance.offset.click.left = inst.offset.click.left;
					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;

					inst._trigger("toSortable", event);
					inst.dropped = this.instance.element; //draggable revert needs that
					//hack so receive/update callbacks work (mostly)
					inst.currentItem = inst.element;
					this.instance.fromOutside = inst;

				}

				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
				if(this.instance.currentItem) this.instance._mouseDrag(event);

			} else {

				//If it doesn't intersect with the sortable, and it intersected before,
				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
				if(this.instance.isOver) {

					this.instance.isOver = 0;
					this.instance.cancelHelperRemoval = true;
					
					//Prevent reverting on this forced stop
					this.instance.options.revert = false;
					
					// The out event needs to be triggered independently
					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
					
					this.instance._mouseStop(event, true);
					this.instance.options.helper = this.instance.options._helper;

					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
					this.instance.currentItem.remove();
					if(this.instance.placeholder) this.instance.placeholder.remove();

					inst._trigger("fromSortable", event);
					inst.dropped = false; //draggable revert needs that
				}

			};

		});

	}
});

$.ui.plugin.add("draggable", "cursor", {
	start: function(event, ui) {
		var t = $('body'), o = $(this).data('draggable').options;
		if (t.css("cursor")) o._cursor = t.css("cursor");
		t.css("cursor", o.cursor);
	},
	stop: function(event, ui) {
		var o = $(this).data('draggable').options;
		if (o._cursor) $('body').css("cursor", o._cursor);
	}
});

$.ui.plugin.add("draggable", "iframeFix", {
	start: function(event, ui) {
		var o = $(this).data('draggable').options;
		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
			.css({
				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
				position: "absolute", opacity: "0.001", zIndex: 1000
			})
			.css($(this).offset())
			.appendTo("body");
		});
	},
	stop: function(event, ui) {
		$("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
	}
});

$.ui.plugin.add("draggable", "opacity", {
	start: function(event, ui) {
		var t = $(ui.helper), o = $(this).data('draggable').options;
		if(t.css("opacity")) o._opacity = t.css("opacity");
		t.css('opacity', o.opacity);
	},
	stop: function(event, ui) {
		var o = $(this).data('draggable').options;
		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
	}
});

$.ui.plugin.add("draggable", "scroll", {
	start: function(event, ui) {
		var i = $(this).data("draggable");
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
	},
	drag: function(event, ui) {

		var i = $(this).data("draggable"), o = i.options, scrolled = false;

		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {

			if(!o.axis || o.axis != 'x') {
				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
			}

			if(!o.axis || o.axis != 'y') {
				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
			}

		} else {

			if(!o.axis || o.axis != 'x') {
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
			}

			if(!o.axis || o.axis != 'y') {
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
			}

		}

		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(i, event);

	}
});

$.ui.plugin.add("draggable", "snap", {
	start: function(event, ui) {

		var i = $(this).data("draggable"), o = i.options;
		i.snapElements = [];

		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
			var $t = $(this); var $o = $t.offset();
			if(this != i.element[0]) i.snapElements.push({
				item: this,
				width: $t.outerWidth(), height: $t.outerHeight(),
				top: $o.top, left: $o.left
			});
		});

	},
	drag: function(event, ui) {

		var inst = $(this).data("draggable"), o = inst.options;
		var d = o.snapTolerance;

		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;

		for (var i = inst.snapElements.length - 1; i >= 0; i--){

			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;

			//Yes, I know, this is insane ;)
			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
				inst.snapElements[i].snapping = false;
				continue;
			}

			if(o.snapMode != 'inner') {
				var ts = Math.abs(t - y2) <= d;
				var bs = Math.abs(b - y1) <= d;
				var ls = Math.abs(l - x2) <= d;
				var rs = Math.abs(r - x1) <= d;
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
			}

			var first = (ts || bs || ls || rs);

			if(o.snapMode != 'outer') {
				var ts = Math.abs(t - y1) <= d;
				var bs = Math.abs(b - y2) <= d;
				var ls = Math.abs(l - x1) <= d;
				var rs = Math.abs(r - x2) <= d;
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
			}

			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);

		};

	}
});

$.ui.plugin.add("draggable", "stack", {
	start: function(event, ui) {

		var o = $(this).data("draggable").options;

		var group = $.makeArray($(o.stack.group)).sort(function(a,b) {
			return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);
		});

		$(group).each(function(i) {
			this.style.zIndex = o.stack.min + i;
		});

		this[0].style.zIndex = o.stack.min + group.length;

	}
});

$.ui.plugin.add("draggable", "zIndex", {
	start: function(event, ui) {
		var t = $(ui.helper), o = $(this).data("draggable").options;
		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
		t.css('zIndex', o.zIndex);
	},
	stop: function(event, ui) {
		var o = $(this).data("draggable").options;
		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
	}
});

})(jQuery);

/*
 * jQuery UI Droppable 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Droppables
 *
 * Depends:
 *	ui.core.js
 *	ui.draggable.js
 */
(function($) {

$.widget("ui.droppable", {

	_init: function() {

		var o = this.options, accept = o.accept;
		this.isover = 0; this.isout = 1;

		this.options.accept = this.options.accept && $.isFunction(this.options.accept) ? this.options.accept : function(d) {
			return d.is(accept);
		};

		//Store the droppable's proportions
		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };

		// Add the reference and positions to the manager
		$.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || [];
		$.ui.ddmanager.droppables[this.options.scope].push(this);

		(this.options.addClasses && this.element.addClass("ui-droppable"));

	},

	destroy: function() {
		var drop = $.ui.ddmanager.droppables[this.options.scope];
		for ( var i = 0; i < drop.length; i++ )
			if ( drop[i] == this )
				drop.splice(i, 1);

		this.element
			.removeClass("ui-droppable ui-droppable-disabled")
			.removeData("droppable")
			.unbind(".droppable");
	},

	_setData: function(key, value) {

		if(key == 'accept') {
			this.options.accept = value && $.isFunction(value) ? value : function(d) {
				return d.is(value);
			};
		} else {
			$.widget.prototype._setData.apply(this, arguments);
		}

	},

	_activate: function(event) {
		var draggable = $.ui.ddmanager.current;
		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
		(draggable && this._trigger('activate', event, this.ui(draggable)));
	},

	_deactivate: function(event) {
		var draggable = $.ui.ddmanager.current;
		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
	},

	_over: function(event) {

		var draggable = $.ui.ddmanager.current;
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element

		if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
			this._trigger('over', event, this.ui(draggable));
		}

	},

	_out: function(event) {

		var draggable = $.ui.ddmanager.current;
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element

		if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
			this._trigger('out', event, this.ui(draggable));
		}

	},

	_drop: function(event,custom) {

		var draggable = custom || $.ui.ddmanager.current;
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element

		var childrenIntersection = false;
		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
			var inst = $.data(this, 'droppable');
			if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
				childrenIntersection = true; return false;
			}
		});
		if(childrenIntersection) return false;

		if(this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
			this._trigger('drop', event, this.ui(draggable));
			return this.element;
		}

		return false;

	},

	ui: function(c) {
		return {
			draggable: (c.currentItem || c.element),
			helper: c.helper,
			position: c.position,
			absolutePosition: c.positionAbs, //deprecated
			offset: c.positionAbs
		};
	}

});

$.extend($.ui.droppable, {
	version: "1.7.2",
	eventPrefix: 'drop',
	defaults: {
		accept: '*',
		activeClass: false,
		addClasses: true,
		greedy: false,
		hoverClass: false,
		scope: 'default',
		tolerance: 'intersect'
	}
});

$.ui.intersect = function(draggable, droppable, toleranceMode) {

	if (!droppable.offset) return false;

	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
	var l = droppable.offset.left, r = l + droppable.proportions.width,
		t = droppable.offset.top, b = t + droppable.proportions.height;

	switch (toleranceMode) {
		case 'fit':
			return (l < x1 && x2 < r
				&& t < y1 && y2 < b);
			break;
		case 'intersect':
			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
			break;
		case 'pointer':
			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
			return isOver;
			break;
		case 'touch':
			return (
					(y1 >= t && y1 <= b) ||	// Top edge touching
					(y2 >= t && y2 <= b) ||	// Bottom edge touching
					(y1 < t && y2 > b)		// Surrounded vertically
				) && (
					(x1 >= l && x1 <= r) ||	// Left edge touching
					(x2 >= l && x2 <= r) ||	// Right edge touching
					(x1 < l && x2 > r)		// Surrounded horizontally
				);
			break;
		default:
			return false;
			break;
		}

};

/*
	This manager tracks offsets of draggables and droppables
*/
$.ui.ddmanager = {
	current: null,
	droppables: { 'default': [] },
	prepareOffsets: function(t, event) {

		var m = $.ui.ddmanager.droppables[t.options.scope];
		var type = event ? event.type : null; // workaround for #2317
		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();

		droppablesLoop: for (var i = 0; i < m.length; i++) {

			if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue

			m[i].offset = m[i].element.offset();
			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };

			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables

		}

	},
	drop: function(draggable, event) {

		var dropped = false;
		$.each($.ui.ddmanager.droppables[draggable.options.scope], function() {

			if(!this.options) return;
			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
				dropped = this._drop.call(this, event);

			if (!this.options.disabled && this.visible && this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
				this.isout = 1; this.isover = 0;
				this._deactivate.call(this, event);
			}

		});
		return dropped;

	},
	drag: function(draggable, event) {

		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);

		//Run through all droppables and check their positions based on specific tolerance options

		$.each($.ui.ddmanager.droppables[draggable.options.scope], function() {

			if(this.options.disabled || this.greedyChild || !this.visible) return;
			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);

			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
			if(!c) return;

			var parentInstance;
			if (this.options.greedy) {
				var parent = this.element.parents(':data(droppable):eq(0)');
				if (parent.length) {
					parentInstance = $.data(parent[0], 'droppable');
					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
				}
			}

			// we just moved into a greedy child
			if (parentInstance && c == 'isover') {
				parentInstance['isover'] = 0;
				parentInstance['isout'] = 1;
				parentInstance._out.call(parentInstance, event);
			}

			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
			this[c == "isover" ? "_over" : "_out"].call(this, event);

			// we just moved out of a greedy child
			if (parentInstance && c == 'isout') {
				parentInstance['isout'] = 0;
				parentInstance['isover'] = 1;
				parentInstance._over.call(parentInstance, event);
			}
		});

	}
};

})(jQuery);

var MM_contentVersion = 7;
var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
if ( plugin ) {
		var words = navigator.plugins["Shockwave Flash"].description.split(" ");
	    for (var i = 0; i < words.length; ++i)
	    {
		if (isNaN(parseInt(words[i])))
		continue;
		var MM_PluginVersion = words[i]; 
	    }
	var MM_FlashCanPlay = MM_PluginVersion >= MM_contentVersion;
}
else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0 
   && (navigator.appVersion.indexOf("Win") != -1)) {
	document.write('<SCR' + 'IPT LANGUAGE=VBScript\> \n'); //FS hide this from IE4.5 Mac by splitting the tag
	document.write('on error resume next \n');
	document.write('MM_FlashCanPlay = ( IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & MM_contentVersion)))\n');
	document.write('</SCR' + 'IPT\> \n');
}
/*
 * jQuery Calculation Plug-in
 *
 * Copyright (c) 2007 Dan G. Switzer, II
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: 5
 * Version: 0.4
 *
 * Revision History
 * v0.4
 * - Added support for -$.99 values
 * - Fixed regex so that decimal values without leading zeros are correctly
 *   parsed
 * - Removed defaults.comma setting
 * - Changed secondary regex that cleans additional formatting from parsed
 *   number
 * 
 * v0.3
 * - Refactored the aggregate methods (since they all use the same core logic)
 *   to use the $.extend() method
 * - Added support for negative numbers in the regex)
 * - Added min/max aggregate methods
 * - Added defaults.onParseError and defaults.onParseClear methods to add logic for
 *   parsing errors
 * 
 * v0.2
 * - Fixed bug in sMethod in calc() (was using getValue, should have been setValue)
 * - Added arguments for sum() to allow auto-binding with callbacks
 * - Added arguments for avg() to allow auto-binding with callbacks
 * 
 * v0.1a
 * - Added semi-colons after object declaration (for min protection)
 * 
 * v0.1
 * - First public release
 *
*/
(function($){

	// set the defaults
	var defaults = {
		// regular expression used to detect numbers, if you want to force the field to contain
		// numbers, you can add a ^ to the beginning or $ to the end of the regex to force the
		// the regex to match the entire string: /^(-|-\$)?(\d+(,\d{3})*(\.\d{1,})?|\.\d{1,})$/g
		reNumbers: /(-|-\$)?(\d+(,\d{3})*(\.\d{1,})?|\.\d{1,})/g
		// should the Field plug-in be used for getting values of :input elements?
		, useFieldPlugin: (!!$.fn.getValue)
		// a callback function to run when an parsing error occurs
		, onParseError: null
		// a callback function to run once a parsing error has cleared
		, onParseClear: null
	};
	
	// set default options
	$.Calculation = {
		version: "0.4",
		setDefaults: function(options){
			$.extend(defaults, options);
		}
	};


	/*
	 * jQuery.fn.parseNumber()
	 *
	 * returns Array - detects the DOM element and returns it's value. input
	 *                 elements return the field value, other DOM objects
	 *                 return their text node
	 *
	 * NOTE: Breaks the jQuery chain, since it returns a Number.
	 *
	 * Examples:
	 * $("input[@name^='price']").parseNumber();
	 * > This would return an array of potential number for every match in the selector
	 *
	 */
	// the parseNumber() method -- break the chain
	$.fn.parseNumber = function(options){
		var aValues = [];
		options = $.extend(options, defaults);
		
		this.each(
			function (){
				var
					// get a pointer to the current element
					$el = $(this),
					// determine what method to get it's value
					sMethod = ($el.is(":input") ? (defaults.useFieldPlugin ? "getValue" : "val") : "text"),
					// parse the string and get the first number we find
					v = $el[sMethod]().match(defaults.reNumbers, "");

				// if the value is null, use 0
				if( v == null ){
					v = 0; // update value
					// if there's a error callback, execute it
					if( jQuery.isFunction(options.onParseError) ) options.onParseError.apply($el, [sMethod]);
					$.data($el[0], "calcParseError", true);
				// otherwise we take the number we found and remove any commas
				} else {
					// clense the number one more time to remove extra data (like commas and dollar signs)
					v = v[0].replace(/[^0-9.\-]/g, "");
					// if there's a clear callback, execute it
					if( $.data($el[0], "calcParseError") && jQuery.isFunction(options.onParseClear) ){
						options.onParseClear.apply($el, [sMethod]);
						// clear the error flag
						$.data($el[0], "calcParseError", false);
					} 
				}
				aValues.push(parseFloat(v, 10));
			}
		);

		// return an array of values
		return aValues;
	};

	/*
	 * jQuery.fn.calc()
	 *
	 * returns Number - performance a calculation and updates the field
	 *
	 * Examples:
	 * $("input[@name='price']").calc();
	 * > This would return the sum of all the fields named price
	 *
	 */
	// the calc() method
	$.fn.calc = function(expr, vars, cbFormat, cbDone){
		var
			// create a pointer to the jQuery object
			$this = this,
			// the value determine from the expression
			exprValue = "",
			// a pointer to the current jQuery element
			$el,
			// store an altered copy of the vars
			parsedVars = {},
			// temp variable
			tmp,
			// the current method to use for updating the value
			sMethod,
			// a hash to store the local variables
			hVars,
			// track whether an error occured in the calculation
			bIsError = false;

		// look for any jQuery objects and parse the results into numbers			
		for( var k in vars ){
			if( !!vars[k] && !!vars[k].jquery ){
				parsedVars[k] = vars[k].parseNumber();
			} else {
				parsedVars[k] = vars[k];
			}
		}
		
		this.each(
			function (i, el){
				// get a pointer to the current element
				$el = $(this);
				// determine what method to get it's value
				sMethod = ($el.is(":input") ? (defaults.useFieldPlugin ? "setValue" : "val") : "text");

				// initialize the hash vars
				hVars = {};
				for( var k in parsedVars ){
					if( typeof parsedVars[k] == "number" ){
						hVars[k] = parsedVars[k];
					} else if( typeof parsedVars[k] == "string" ){
						hVars[k] = parseFloat(parsedVars[k], 10);
					} else if( !!parsedVars[k] && (parsedVars[k] instanceof Array) ) {
						// if the length of the array is the same as number of objects in the jQuery
						// object we're attaching to, use the matching array value, otherwise use the
						// value from the first array item
						tmp = (parsedVars[k].length == $this.length) ? i : 0;
						hVars[k] = parsedVars[k][tmp];
					}
					
					// if we're not a number, make it 0
					if( isNaN(hVars[k]) ) hVars[k] = 0;
				}

				// try the calculation
				try {
					exprValue = eval( expr.replace(/([A-Za-z]+)/g, "hVars.$1") );
					
					// if there's a format callback, call it now
					if( !!cbFormat ) exprValue = cbFormat(exprValue);
		
				// if there's an error, capture the error output
				} catch(e){
					exprValue = e;
					bIsError = true;
				}
				
				// update the value
				$el[sMethod](exprValue.toString());
			}
		);
		
		// if there's a format callback, call it now
		if( !!cbDone ) cbDone(this);

		return this;
	};

	/*
	 * Define all the core aggregate functions. All of the following methods
	 * have the same functionality, but they perform different aggregate 
	 * functions.
	 * 
	 * If this methods are called without any arguments, they will simple
	 * perform the specified aggregate function and return the value. This
	 * will break the jQuery chain. 
	 * 
	 * However, if you invoke the method with any arguments then a jQuery
	 * object is returned, which leaves the chain intact.
	 * 
	 * 
	 * jQuery.fn.sum()
	 * returns Number - the sum of all fields
	 *
	 * jQuery.fn.avg()
	 * returns Number - the avg of all fields
	 *
	 * jQuery.fn.min()
	 * returns Number - the minimum value in the field
	 *
	 * jQuery.fn.max()
	 * returns Number - the maximum value in the field
	 * 
	 * Examples:
	 * $("input[@name='price']").sum();
	 * > This would return the sum of all the fields named price
	 *
	 * $("input[@name='price1'], input[@name='price2'], input[@name='price3']").sum();
	 * > This would return the sum of all the fields named price1, price2 or price3
	 *
	 * $("input[@name^=sum]").sum("keyup", "#totalSum");
	 * > This would update the element with the id "totalSum" with the sum of all the 
	 * > fields whose name started with "sum" anytime the keyup event is triggered on
	 * > those field.
	 *
	 * NOTE: The syntax above is valid for any of the aggregate functions
	 *
	 */
	$.each(["sum", "avg", "min", "max"], function (i, method){
		$.fn[method] = function (bind, selector){
			// if no arguments, then return the result of the aggregate function
			if( arguments.length == 0 )
				return math[method](this.parseNumber());
	
			// if the selector is an options object, get the options
			var bSelOpt = selector && selector.constructor == Object && !(selector instanceof jQuery);
			
			// configure the options for this method
			var opt = bind && bind.constructor == Object ? bind : {
				  bind: "keyup"
				, selector: (!bSelOpt) ? selector : null
				, oncalc: null
			};
	
			// if the selector is an options object, extend	the options
			if( bSelOpt ) opt = jQuery.extend(opt, selector);
			
			// if the selector exists, make sure it's a jQuery object
			if( !!opt.selector ) opt.selector = $(opt.selector);
			
			var self = this
				, sMethod
				, doCalc = function (){
					// preform the aggregate function
					var value = math[method](self.parseNumber(opt));
					// check to make sure we have a selector				
					if( !!opt.selector ){
						// determine how to set the value for the selector
						sMethod = (opt.selector.is(":input") ? (defaults.useFieldPlugin ? "setValue" : "val") : "text");
						// update the value
						opt.selector[sMethod](value);
					}
					// if there's a callback, run it now
					if( jQuery.isFunction(opt.oncalc) ) opt.oncalc.apply(self, [value, opt]);
				};
			
			// perform the aggregate function now, to ensure init values are updated
			doCalc();
			
			// bind the doCalc function to run each time a key is pressed
			return self.bind(opt.bind, doCalc);
		}
	});
	
	/*
	 * Mathmatical functions
	 */
	var math = {
		// sum an array
		sum: function (a){
			var total = 0;
			
			// loop through the value and total them
			$.each(a, function (i, v){
				// we add 0 to the value to ensure we get a numberic value
				total += v;
			});
	
			// return the values as a comma-delimited string
			return total;
		},
		// average an array
		avg: function (a){
			// return the values as a comma-delimited string
			return math.sum(a)/a.length;
		},
		// lowest number in array
		min: function (a){
			return Math.min.apply(Math, a);
		},
		// highest number in array
		max: function (a){
			return Math.max.apply(Math, a);
		}
	};
	

})(jQuery);

//v1.0
//Copyright 2006 Adobe Systems, Inc. All rights reserved.
function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '<object ';
  for (var i in objAttrs)
    str += i + '="' + objAttrs[i] + '" ';
  str += '>';
  for (var i in params)
    str += '<param name="' + i + '" value="' + params[i] + '" /> ';
  str += '<embed ';
  for (var i in embedAttrs)
    str += i + '="' + embedAttrs[i] + '" ';
  str += ' ></embed></object>';

  document.write(str);
}

function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "id":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}

// JavaScript Document
var sFlashNote = '<img src="\/images\/flash_placeholder.jpg" alt="' + 'flash'.t() + '" \/>';
var sFlashNote2 = '<img src="\/images\/virgin_flash_place_holder.gif" alt="' + 'Sponsor'.t() + '" \/>';


// R.Livsey, 2009
// rewritten from JQuery to Prototype to make it easier to add features & extend
var AutoScroller = Class.create({
  
  steps: 1,       // px to scroll each iteration
  delay: 100,     // delay in ms between iterations
  buffer: 20,     // only scroll if there's at least this many px of area
  direction: 'down',
  
  initialize: function(container, options)
  {
    Object.extend(this, options);
    
    this.container = container;    
    this.container.observe('mouseover', this.pause.bind(this));
    this.container.observe('mouseout',  this.start.bind(this));    
    this.calculate();
    this.start();
  },
  
  start: function()
  {
    // if the height of the box is smaller than the scroll area,
    // don't even bother to run as it'll just sit there eating resource
    if ((this.height + this.buffer) >= this.available_height)
    {
      return;
    }    
    
    if (!this._interval)
    {
      this._interval = setInterval(this.scroll.bind(this), this.delay);
    }
  },
  
  pause: function()
  {
    if (this._interval)
    {
      clearInterval(this._interval);
      this._interval = null;
    }
  },
  
  scroll: function()
  {
    var x = parseInt(this.container.scrollTop, 0);
    if (this.direction == 'down' && x >= (this.available_height - this.height))
    {
      this.direction = 'up';
    }
    else if (x === 0)
    {
      this.direction = 'down';
    }
    this.container.scrollTop = x + (this.direction == 'down' ? this.steps : -this.steps);
  },
  
  calculate: function()
  {
    this.height           = this.container.getHeight();
    this.available_height = this.container.scrollHeight;    
  },
  
  recalculate: function()
  {
    this.pause();
    this.calculate();
    this.start();
  }
  
});

// kick it off on all elements with an autoScroll class when the dom loads
document.observe('dom:loaded', function(){
 $$('.autoscroll > div').each(function(el){
   new AutoScroller(el);
 });
});


langHover = function() {
   $J("#langSelect").hover(
     function(){$J("#langOptions", this).show();},
     function() {$J("#langOptions", this).hide();}
   );
  $J('#langOptions li').hover(
			function() { $J('#langOptions', this).show();},
			function() { $J('#langOptions', this).hide();}
	)
}

accountHover = function() {
	$J("#accountDetails p").hover(
	  function() {$J("#userAccountDetails").show();},
		function(){$J("#userAccountDetails").hide();}
		)
}

decimalsHover = function() {
  
  $J('#decimals').click(function(){
    $J('#decimalOptions').toggle();
    });
}

balanceHover = function() {
  $J("#balanceValueContainer").hover(
    function(){$J("#balanceDetail").show();},
    function(){$J("#balanceDetail").hide()
    })
}





var SlideToggleObserver = Class.create({
  
  initialize: function()
  {
    document.observe('click', this.clicked.bindAsEventListener(this));
  },
  
  clicked: function(e)
  {
    var element = e.element();
    
    // if it's not a link, see if it's inside a link
    if (element.nodeName != 'A')
    {
      element = element.up('a');
    }

    // bail if not a link with closeSlide/openSlide class
    if (!element || !(element.hasClassName('openSlide') || element.hasClassName('closeSlide')) )
    {
      return;
    }
    
    e.stop();
    
    element.toggleClassName('openSlide');
    element.toggleClassName('closeSlide');

    // get the element we want to toggle
    // different parts of the app use slide and others moneySlide
    // todo DRY this up so we only use one class
    var slide = element.up('div').down('.slide') || element.up('div').down('.moneySlide');
    
    // toggle it
    // TODO - use scriptaculous instead of JQuery effects

		$J(slide).toggle();
    
    // did we open it or close it?
    var state = element.hasClassName('openSlide') ? 'opened' : 'closed';    
    
    // fire an event so other JS can be notified
    document.fire('slider:toggled', {state: state, element: element});
  }
  
});

document.observe('dom:loaded', function(){
  new SlideToggleObserver();
});
/*
 * Tabs 3 - New Wave Tabs
 *
 * Copyright (c) 2007 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 */

(function($) {

    // if the UI scope is not availalable, add it
    $.ui = $.ui || {};

    // tabs initialization
    $.fn.tabs = function(initial, options) {
        if (initial && initial.constructor == Object) { // shift arguments
            options = initial;
            initial = null;
        }
        options = options || {};

        initial = initial && initial.constructor == Number && --initial || 0;

        return this.each(function() {
            new $.ui.tabs(this, $.extend(options, { initial: initial }));
        });
    };

    // other chainable tabs methods
    $.each(['Add', 'Remove', 'Enable', 'Disable', 'Click', 'Load', 'Href'], function(i, method) {
        $.fn['tabs' + method] = function() {
            var args = arguments;
            return this.each(function() {
                var instance = $.ui.tabs.getInstance(this);
                instance[method.toLowerCase()].apply(instance, args);
            });
        };
    });
    $.fn.tabsSelected = function() {
        var selected = -1;
        if (this[0]) {
            var instance = $.ui.tabs.getInstance(this[0]), $lis = $('li', this);
            selected = $lis.index( $lis.filter('.' + instance.options.selectedClass)[0] );
            $lis = null; // clean-up to avoid memory leaks in certain unpatched versions of IE 6
        }
        return selected >= 0 ? ++selected : -1;
    };

    // tabs class
    $.ui.tabs = function(el, options) {

        this.source = el;

        this.options = $.extend({

            // basic setup
            initial: 0,
            event: 'click',
            disabled: [],
            cookie: null, // pass options object as expected by cookie plugin: { expires: 7, path: '/', domain: 'jquery.com', secure: true }
            // TODO bookmarkable: $.ajaxHistory ? true : false,
            unselected: false,
            unselect: options.unselected ? true : false,

            // Ajax
            spinner: 'Loading&#8230;',
            cache: false,
            idPrefix: 'ui-tabs-',
            ajaxOptions: {},

            // animations
            /*fxFade: null,
            fxSlide: null,
            fxShow: null,
            fxHide: null,*/
            fxSpeed: 'normal',
            /*fxShowSpeed: null,
            fxHideSpeed: null,*/

            // callbacks
            add: function() {},
            remove: function() {},
            enable: function() {},
            disable: function() {},
            click: function() {},
            hide: function() {},
            show: function() {},
            load: function() {},
            
            // templates
            tabTemplate: '<li><a href="#{href}"><span>#{text}</span></a></li>',
            panelTemplate: '<div></div>',

            // CSS classes
            navClass: 'ui-tabs-nav',
            selectedClass: 'ui-tabs-selected',
            unselectClass: 'ui-tabs-unselect',
            disabledClass: 'ui-tabs-disabled',
            panelClass: 'ui-tabs-panel',
            hideClass: 'ui-tabs-hide',
            loadingClass: 'ui-tabs-loading'

        }, options);

        this.options.event += '.ui-tabs'; // namespace event
        this.options.cookie = $.cookie && $.cookie.constructor == Function && this.options.cookie;

        // save instance for later
        $.data(el, $.ui.tabs.INSTANCE_KEY, this);
        
        // create tabs
        this.tabify(true);
    };

    // static
    $.ui.tabs.INSTANCE_KEY = 'ui_tabs_instance';
    $.ui.tabs.getInstance = function(el) {
        return $.data(el, $.ui.tabs.INSTANCE_KEY);
    };

    // instance methods
    $.extend($.ui.tabs.prototype, {
        tabId: function(a) {
            return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
                || this.options.idPrefix + $.data(a);
        },
        tabify: function(init) {

            this.$lis = $('li:has(a[href])', this.source);
            this.$tabs = this.$lis.map(function() { return $('a', this)[0] });
            this.$panels = $([]);
            
            var self = this, o = this.options;
            
            this.$tabs.each(function(i, a) {
                // inline tab
                if (a.hash && a.hash.replace('#', '')) { // Safari 2 reports '#' for an empty hash
                    self.$panels = self.$panels.add(a.hash);
                }
                // remote tab
                else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
                    $.data(a, 'href', a.href);
                    var id = self.tabId(a);
                    a.href = '#' + id;
                    self.$panels = self.$panels.add(
                        $('#' + id)[0] || $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
                            .insertAfter( self.$panels[i - 1] || self.source )
                    );
                }
                // invalid tab href
                else {
                    o.disabled.push(i + 1);
                }
            });

            if (init) {

                // attach necessary classes for styling if not present
                $(this.source).hasClass(o.navClass) || $(this.source).addClass(o.navClass);
                this.$panels.each(function() {
                    var $this = $(this);
                    $this.hasClass(o.panelClass) || $this.addClass(o.panelClass);
                });
                
                // disabled tabs
                for (var i = 0, position; position = o.disabled[i]; i++) {
                    this.disable(position);
                }
                
                // Try to retrieve initial tab:
                // 1. from fragment identifier in url if present
                // 2. from cookie
                // 3. from selected class attribute on <li>
                // 4. otherwise use given initial argument
                // 5. check if tab is disabled
                this.$tabs.each(function(i, a) {
                    if (location.hash) {
                        if (a.hash == location.hash) {
                            o.initial = i;
                            // prevent page scroll to fragment
                            //if (($.browser.msie || $.browser.opera) && !o.remote) {
                            if ($.browser.msie || $.browser.opera) {
                                var $toShow = $(location.hash), toShowId = $toShow.attr('id');
                                $toShow.attr('id', '');
                                setTimeout(function() {
                                    $toShow.attr('id', toShowId); // restore id
                                }, 500);
                            }
                            scrollTo(0, 0);
                            return false; // break
                        }
                    } else if (o.cookie) {
                        var p = parseInt($.cookie($.ui.tabs.INSTANCE_KEY + $.data(self.source)));
                        if (p && self.$tabs[p]) {
                            o.initial = p;
                            return false; // break
                        }
                    } else if ( self.$lis.eq(i).hasClass(o.selectedClass) ) {
                        o.initial = i;
                        return false; // break
                    }
                });
                var n = this.$lis.length;
                while (this.$lis.eq(o.initial).hasClass(o.disabledClass) && n) {
                    o.initial = ++o.initial < this.$lis.length ? o.initial : 0;
                    n--;
                }
                if (!n) { // all tabs disabled, set option unselected to true
                    o.unselected = o.unselect = true;
                }

                // highlight selected tab
                this.$panels.addClass(o.hideClass);
                this.$lis.removeClass(o.selectedClass);
                if (!o.unselected) {
                    this.$panels.eq(o.initial).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
                    this.$lis.eq(o.initial).addClass(o.selectedClass);
                }

                // load if remote tab
                var href = !o.unselected && $.data(this.$tabs[o.initial], 'href');
                if (href) {
                    this.load(o.initial + 1, href);
                }
                
                // disable click if event is configured to something else
                if (!/^click/.test(o.event)) {
                    this.$tabs.bind('click', function(e) { e.preventDefault(); });
                }
                
                // clean-up to avoid memory leaks in certain unpatched versions of IE 6
                $(window).unload(function() {
                    self.$tabs.unbind(o.event);
                    self.$lis = self.$tabs = self.$panels = null;
                });

            }

            // setup animations
            var showAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed,
                hideAnim = {}, hideSpeed = o.fxHideSpeed || o.fxSpeed;
            if (o.fxSlide || o.fxFade) {
                if (o.fxSlide) {
                    showAnim['height'] = 'show';
                    hideAnim['height'] = 'hide';
                }
                if (o.fxFade) {
                    showAnim['opacity'] = 'show';
                    hideAnim['opacity'] = 'hide';
                }
            } else {
                if (o.fxShow) {
                    showAnim = o.fxShow;
                } else { // use some kind of animation to prevent browser scrolling to the tab
                    showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
                    showSpeed = 1; // as little as 1 is sufficient
                }
                if (o.fxHide) {
                    hideAnim = o.fxHide;
                } else { // use some kind of animation to prevent browser scrolling to the tab
                    hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
                    hideSpeed = 1; // as little as 1 is sufficient
                }
            }

            // reset some styles to maintain print style sheets etc.
            var resetCSS = { display: '', overflow: '', height: '' };
            if (!$.browser.msie) { // not in IE to prevent ClearType font issue
                resetCSS['opacity'] = '';
            }

            // Hide a tab, animation prevents browser scrolling to fragment,
            // $show is optional.
            function hideTab(clicked, $hide, $show) {
                $hide.animate(hideAnim, hideSpeed, function() { //
                    $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
                    if ($.browser.msie && hideAnim['opacity']) {
                        $hide[0].style.filter = '';
                    }
                    o.hide(clicked, $hide[0], $show && $show[0] || null);
                    if ($show) {
                        showTab(clicked, $show, $hide);
                    }
                });
            }

            // Show a tab, animation prevents browser scrolling to fragment,
            // $hide is optional
            function showTab(clicked, $show, $hide) {
                if (!(o.fxSlide || o.fxFade || o.fxShow)) {
                    $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
                }
                $show.animate(showAnim, showSpeed, function() {
                    $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
                    if ($.browser.msie && showAnim['opacity']) {
                        $show[0].style.filter = '';
                    }
                    o.show(clicked, $show[0], $hide && $hide[0] || null);
                });
            }

            // switch a tab
            function switchTab(clicked, $li, $hide, $show) {
                /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
                    $.ajaxHistory.update(clicked.hash);
                }*/
                $li.addClass(o.selectedClass)
                    .siblings().removeClass(o.selectedClass);
                hideTab(clicked, $hide, $show);
            }

            // attach tab event handler, unbind to avoid duplicates from former tabifying...
            this.$tabs.unbind(o.event).bind(o.event, function() {

                //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
                var $li = $(this).parents('li:eq(0)'),
                    $hide = self.$panels.filter(':visible'),
                    $show = $(this.hash);

                // If tab is already selected and not unselectable or tab disabled or click callback returns false stop here.
                // Check if click handler returns false last so that it is not executed for a disabled tab!
                if (($li.hasClass(o.selectedClass) && !o.unselect) || $li.hasClass(o.disabledClass)
                    || o.click(this, $show[0], $hide[0]) === false) {
                    this.blur();
                    return false;
                }
                
                if (o.cookie) {
                    $.cookie($.ui.tabs.INSTANCE_KEY + $.data(self.source), self.$tabs.index(this), o.cookie);
                }
                    
                // if tab may be closed
                if (o.unselect) {
                    if ($li.hasClass(o.selectedClass)) {
                        $li.removeClass(o.selectedClass);
                        self.$panels.stop();
                        hideTab(this, $hide);
                        this.blur();
                        return false;
                    } else if (!$hide.length) {
                        self.$panels.stop();
                        if ($.data(this, 'href')) { // remote tab
                            var a = this;
                            self.load(self.$tabs.index(this) + 1, $.data(this, 'href'), function() {
                                $li.addClass(o.selectedClass).addClass(o.unselectClass);
                                showTab(a, $show);
                            });
                        } else {
                            $li.addClass(o.selectedClass).addClass(o.unselectClass);
                            showTab(this, $show);
                        }
                        this.blur();
                        return false;
                    }
                }

                // stop possibly running animations
                self.$panels.stop();

                // show new tab
                if ($show.length) {

                    // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
                    /*if ($.browser.msie && o.bookmarkable) {
                        var showId = this.hash.replace('#', '');
                        $show.attr('id', '');
                        setTimeout(function() {
                            $show.attr('id', showId); // restore id
                        }, 0);
                    }*/

                    if ($.data(this, 'href')) { // remote tab
                        var a = this;
                        self.load(self.$tabs.index(this) + 1, $.data(this, 'href'), function() {
                            switchTab(a, $li, $hide, $show);
                        });
                    } else {
                        switchTab(this, $li, $hide, $show);
                    }

                    // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
                    /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
                    var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
                    setTimeout(function() {
                        scrollTo(scrollX, scrollY);
                    }, 0);*/

                } else {
                    throw 'jQuery UI Tabs: Mismatching fragment identifier.';
                }

                // Prevent IE from keeping other link focussed when using the back button
                // and remove dotted border from clicked link. This is controlled in modern
                // browsers via CSS, also blur removes focus from address bar in Firefox
                // which can become a usability and annoying problem with tabsRotate.
                if ($.browser.msie) {
                    this.blur(); 
                }

                //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
                return false;

            });

        },
        add: function(url, text, position) {
            if (url && text) {
                position = position || this.$tabs.length; // append by default  
                
                var o = this.options,
                    $li = $(o.tabTemplate.replace(/#\{href\}/, url).replace(/#\{text\}/, text));
                
                var id = url.indexOf('#') == 0 ? url.replace('#', '') : this.tabId( $('a:first-child', $li)[0] );
                
                // try to find an existing element before creating a new one
                var $panel = $('#' + id);
                $panel = $panel.length && $panel
                    || $(o.panelTemplate).attr('id', id).addClass(o.panelClass).addClass(o.hideClass);
                if (position >= this.$lis.length) {
                    $li.appendTo(this.source);
                    $panel.appendTo(this.source.parentNode);
                } else {
                    $li.insertBefore(this.$lis[position - 1]);
                    $panel.insertBefore(this.$panels[position - 1]);
                }
                
                this.tabify();
                
                if (this.$tabs.length == 1) {
                     $li.addClass(o.selectedClass);
                     $panel.removeClass(o.hideClass);
                     var href = $.data(this.$tabs[0], 'href');
                     if (href) {
                         this.load(position + 1, href);
                     }
                }
                o.add(this.$tabs[position], this.$panels[position]); // callback
            } else {
                throw 'jQuery UI Tabs: Not enough arguments to add tab.';
            }
        },
        remove: function(position) {
            if (position && position.constructor == Number) {                
                var o = this.options, $li = this.$lis.eq(position - 1).remove(),
                    $panel = this.$panels.eq(position - 1).remove();
                    
                // If selected tab was removed focus tab to the right or
                // tab to the left if last tab was removed.
                if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1) {
                    this.click(position + (position < this.$tabs.length ? 1 : -1));
                }
                this.tabify();
                o.remove($li.end()[0], $panel[0]); // callback
            }
        },
        enable: function(position) {
            var o = this.options, $li = this.$lis.eq(position - 1);
            $li.removeClass(o.disabledClass);
            if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
                $li.css('display', 'inline-block');
                setTimeout(function() {
                    $li.css('display', 'block')
                }, 0)
            }
            o.enable(this.$tabs[position - 1], this.$panels[position - 1]); // callback
        },
        disable: function(position) {
            var o = this.options;      
            this.$lis.eq(position - 1).addClass(o.disabledClass);
            o.disable(this.$tabs[position - 1], this.$panels[position - 1]); // callback
        },
        click: function(position) {
            this.$tabs.eq(position - 1).trigger(this.options.event);
        },
        load: function(position, url, callback) {
            var self = this, o = this.options,
                $a = this.$tabs.eq(position - 1), a = $a[0], $span = $('span', a);
            
            // shift arguments
            if (url && url.constructor == Function) {
                callback = url;
                url = null;
            }

            // set new URL or get existing
            if (url) {
                $.data(a, 'href', url);
            } else {
                url = $.data(a, 'href');
            }

            // load
            if (o.spinner) {
                $.data(a, 'title', $span.html());
                $span.html('<em>' + o.spinner + '</em>');
            }
            var finish = function() {
                self.$tabs.filter('.' + o.loadingClass).each(function() {
                    $(this).removeClass(o.loadingClass);
                    if (o.spinner) {
                        $('span', this).html( $.data(this, 'title') );
                    }
                });
                self.xhr = null;
            };
            var ajaxOptions = $.extend({}, o.ajaxOptions, {
                url: url,
                success: function(r, s) {
                    $(a.hash).html(r);
                    finish();
                    // This callback is required because the switch has to take 
                    // place after loading has completed.
                    if (callback && callback.constructor == Function) {
                        callback();
                    }
                    if (o.cache) {
                        $.removeData(a, 'href'); // if loaded once do not load them again
                    }
                    o.load(self.$tabs[position - 1], self.$panels[position - 1]); // callback
                    o.ajaxOptions.success && o.ajaxOptions.success(r, s);
                }
            });
            if (this.xhr) {
                // terminate pending requests from other tabs and restore title
                this.xhr.abort();
                finish();
            }
            $a.addClass(o.loadingClass);
            setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
                self.xhr = $.ajax(ajaxOptions);
            }, 0);
            
        },
        href: function(position, href) {
            $.data(this.$tabs.eq(position - 1)[0], 'href', href);
        }
    });

})(jQuery);


// Betslip Globals
var singleSelections = new Array();
var multipleSelections = new Array();

function reloadVariables() {
  keepPromocashCheckBox = document.getElementById('current_promocash');
  keepBetsCheckBox = document.getElementById('keep');
  singlesContainer = document.getElementById('betSlipMain');
  multiplesContainer = document.getElementById('betSlipMultiples');
}

// Ajax Queue
var ajaxManager1 = $J.manageAjax({manageType: 'queue', maxReq: 0});
//Initialize the betslip functions, like animations and other things

function reloadCounter() {
	if ((getCookie("bsSingles") == null) || (getCookie("bsSingles") == "")) {
		$J("#betsToPlace").html("Your bet slip is currently empty".t());
	} else {
	    var count = '<a id="betCounter" href="#">' + singleSelections.length + '</a>';
		var countText = 'You have <a id="betCounter" href="#">' + singleSelections.length + '</a> bets waiting to be placed';
	    
		$J("#betsToPlace").html(countText);
        $J('#betCounter').click(function(){
        	betSlipOpen();
   		});
  	}
}

function initBetslip() {

    $J('#betCounter').click(function(){
        betSlipOpen();
    });
    
    $J("#betSlipToggle").click(function(){
       if ($J(this).hasClass("openBetSlip")){
           betSlipOpen();
       } else {
           betSlipClose();
       }
    });

    $J('#betSlipMutiples').hide();
}

function betSlipOpen() {
      $J("#betSlipToggle").removeClass("openBetSlip");
      $J("#betSlipToggle").addClass("closeBetSlip");
      $J("#betSlip .placeBet").show();
      $J("#betSlip #spinner").slideDown('fast');
	  $J('#betsToPlace').hide();
      return false;
}

function betSlipClose(){
      $J("#betSlipToggle").removeClass("closeBetSlip");
      $J("#betSlipToggle").addClass("openBetSlip");
      $J("#betSlip #spinner").slideUp('fast');
      $J("#betSlip .placeBet").hide();
      $J('#betsToPlace').show();
      return false;
}

//Check if the betslip is present or is a message
function check_betslip() {
   if ($J("#betSlipErrorBox").length > 0) {
       return false;
   }
   return true;
}

// quick deposit functions
var quickDeposit = function() {
  
  blockRegion.create('spinner');
  $J('#removeQuickDeposit').click(function(){
    blockRegion.remove('spinner');
    $J('#betslipQuickDeposit').remove();
    return false;
  });
  $J('.placeBet').click(function(){
    blockRegion.remove('spinner');
    blockRegion.create('betslipQuickDeposit');
    $J("#betslipQuickDeposit #blockRegion").css({'top': '0px', 'left': '0px'});
  });
}


function mark_bets_on_coupon(){
	for (s = 0; s < singleSelections.length; s++) {
		mark_added_bets(singleSelections[s].outcome_id);
	}
}

//This function marks prices for a specific outcome as betted
function mark_added_bets(outcome_id) {
  if (outcome_id) {
    $J("a.priceLink"+outcome_id).addClass('betted');
    $J("a.priceLinkInRunning"+outcome_id).addClass('betted');
    $J("span.addToSlip"+outcome_id).html('Added to betslip'.t());
  }
}

// Remove the mark from a bet link, or all if outcome_id is null
function remove_added_bets_mark(outcome_id) {
    if (outcome_id == null) {
      $J("a.betted").removeClass('betted');
    } else {
      $J("a.priceLink"+outcome_id).removeClass('betted');
      $J("a.priceLinkInRunning"+outcome_id).removeClass('betted');
      $J("span.addToSlip"+outcome_id).html('Add to betslip'.t());
    }
}

function check_height(){
	
	if (singleSelections.length < 2) {
		$J('#betSlipMultiples').hide();
	}
}

function check_height_multiples(){

	if (singleSelections.length > 1) {
		if (multipleSelections.length > 0) {
			$J('#betSlipMultiples').show();
		} else if (multipleSelections.length == 0) {
            $J("#betSlipMultiples").hide();
		}	
     }
}
            
//Removes all bets from the betslip
//AJAX call
function remove_all(website, language) {
   for (s = 0; s < singleSelections.length; s++) {
     remove_added_bets_mark(singleSelections[s].outcome_id);
     removeElement(singleSelections[s].outcome_id);
   }
   removeErrorBox();
   singleSelections = [];
   multipleSelections = [];
   setCookie("bsSingles", "", null, "/");
   setCookie("bsMultiples", "", null, "/");
   $J("#multiplesDiv").html("");
   blockRegion.remove('betSlipMultiples');
   remove_added_bets_mark(null);
   betSlipClose();
   reloadCounter();
   updateTotals();
   update_inrunning();
}

//Remove a bet from the slip
function remove_from_slip(website, language, outcome_id, price_id) {
  var newSingles = new Array();
  var cnt = 0;

  for (s = 0; s < singleSelections.length; s++) {
      if (singleSelections[s].outcome_id != outcome_id) {
          newSingles[cnt] = singleSelections[s];
          cnt++;
      } else {
          // Delete Element
          remove_added_bets_mark(outcome_id);
          removeElement(outcome_id);
      }
  }
  singleSelections = newSingles;  
  if (singleSelections.length < 1) {
  	betSlipClose();
  }
  if (singleSelections.length < 2) {
	multipleSelections = [];
	setCookie("bsMultiples", "", null, "/");
	$J("#multiplesDiv").html("");
  }
  removeErrorBox();
  saveBetslip();
  reloadCounter();
  updateMultiples();
  check_height();
  check_height_multiples();
  updateTotals();
  update_inrunning();
}

function removeElement(e) {
  reloadVariables();
  var toRemove = document.getElementById('betBox' + e);
    if (toRemove) {
       singlesContainer.removeChild(toRemove);
    }
}

//Only show the slip with no action
//AJAX call
//All params here are strings
function show_betslip(website, language) {
  blockRegion.create('betSlipErrorBox');
  $J('#betSlip').load('/'+escape(website)+'/'+escape(language)+'/betslip/continue_insufficient_funds',
    {},
    function(){readyBetslip();});
}

//Shows loading animation screen on the betslip
//Used to disable the form on the betslip
function place_bets_loading(){

  if ($J("#fBet").length > 0){
    // if($J("#betSlip > h2").hasClass('openBetTop')){
      // betSlipClose();
      // $J("#betSlip > div > form").slideToggle("slow", function() { blockRegion.create('fBet');});
    // } else {
      blockRegion.create('fBet');
    // }
  } else {
    if ($J("#betSlipErrorBox").length > 0){
        blockRegion.create('betSlipErrorBox');
    } else {
        blockRegion.create('betSlip');
    }
  }
}

//Shows loading animation screen on the betslip
//Used to disable the form on the betslip
function place_bets_remove_loading(){
  blockRegion.remove('fBet');
  blockRegion.remove('betSlipErrorBox');
  blockRegion.remove('betSlip');  
}

//Initializes the betslip and updates the user balance
//AJAX call
//All params here are strings
function place_bets_complete(website, language){
  $J.getScript('/'+escape(website)+'/'+escape(language)+'/balance/refresh?language_id='+language,
      function(){
          initBalance();
      });
  if ($J("#betSlipMain").length > 0) {
    if (getCookie("keepBets")!="yes") {
      singleSelections = [];
      multipleSelections = [];
      $J(singlesContainer).html("");
      $J(multiplesContainer).html("");
      //setCookie("bsSingles", "", null, "/");
	  //setCookie("bsMultiples", "", null, "/");
      remove_added_bets_mark(null);
      if($J("#betSlip > h2").hasClass('openBetTop') && ($J("#fBetDiv").length > 0)){
        //betSlipClose();
      }
    }
  }
  // remove the loading block incase it's still there
  place_bets_remove_loading();
  update_inrunning();
}

function startPriceChange(outcome_id, sp_value) {
    if ($J("#odds"+outcome_id).val() == sp_value) {
        $J("#mult_"+outcome_id).val("0");
    } else {
        $J("#mult_"+outcome_id).val($J("#odds"+outcome_id).val());
    }
    updateTotals();
}

function place_bet_handler(timeToWait) {
    var timing = false;
    var has_any_bet = false;
    
	for (s = 0; s < singleSelections.length; s++) {
		if (parseFloat(singleSelections[s].stake) > 0) {
			has_any_bet = true;
			break;
		}
	}	
	if (!has_any_bet) {
		for (m = 0; m < multipleSelections.length; m++) {
			if (parseFloat(multipleSelections[m].stake) > 0) {
				has_any_bet = true;
				break;
			}
		}
	}
  if (!has_any_bet) {
		alert("You have to enter a stake to place a bet.".t());
		submitting_betslip = false;
	} else {
		
		if (timeToWait > 0) {
		  place_bets_loading();
			countLimit = timeToWait;
			count = countLimit;
			showtime = setInterval(run_timer, 1000);
		} else {
			$J("#submitBetSlip").attr("disabled", false);
			$J("#submitBetSlip").click();
		}
	}
}


function run_timer(){
	if (count == 0) {
     $J("#betslipTimer").html("Loading...".t());
	   clearInterval(showtime);
	   count = countLimit;
     $J("#submitBetSlip").attr("disabled", false);
     $J("#submitBetSlip").click();
	} else {
	   if (count == countLimit) {
	     $J("#betslipTimer").css("z-index", getNextHighestZindex());
		   $J("#betslipTimer").css("display", "block");
	   }
     $J("#betslipTimer").html("Placing your bets in".t()+"<br /><span>"+"{0} seconds".t(count)+"</span>");
	   count--;
	}
}

function onFocusStake(obj) {
  if (obj.value == "" ||  obj.value == "0.00") {
    obj.value = "";
  }
}

function stakeOnBlur(obj) {  
  obj.value = formatStake(obj.value);
  saveBetslip();
  saveMultiplesBetslip();
  updateTotals();
}

function formatStake(stake) {
	var newstake = (parseFloat(stake)).toFixed(2);
	if (isNaN(newstake) || newstake == "" ||  newstake == "0") {
    	newstake = "0.00";
    }
	return newstake;
}

function saveBetslip() {
  // Do Singles
  for (s = 0; s < singleSelections.length; s++) {
      stake = 0;
      if (document.getElementById('stake' + singleSelections[s].outcome_id)) {
        stake = document.getElementById('stake' + singleSelections[s].outcome_id).value;
      }
      if (stake == "" || isNaN(stake)) { stake = 0; }
	
	    parseFloat(stake);
	    singleSelections[s].stake = stake;
	
	    singleSelections[s].each_way = ($J("#eachWay"+ singleSelections[s].outcome_id+":checked").val() != null)?1:0;
      singleSelections[s].price_id = (singleSelections[s].price_id == "")?0:singleSelections[s].price_id
  }
  save_single_betslip(singleSelections);
}

function saveMultiplesBetslip() {
    // Do Multiples
    for (m = 0; m < multipleSelections.length; m++) {
  		if (document.getElementById('unitStake' + multipleSelections[m].bet_type_id)) {
  			stake = document.getElementById('unitStake' + multipleSelections[m].bet_type_id).value;
  			if (stake == "" || isNaN(stake)) { stake = 0; }
		
  			parseFloat(stake);
  			multipleSelections[m].stake = stake;		
  			multipleSelections[m].each_way = ($J("#tEachWay" + multipleSelections[m].bet_type_id + ":checked").val() != null) ?1:0;
  		}
    }
    save_multiples_betslip(multipleSelections);
}

function saveKeepCheckBox(checkBox){
  if (checkBox.checked) {
    setCookie("keepBets", "yes", null, "/");
  } else {
    setCookie("keepBets", "", null, "/");
  }
}

function savePromocashCheckBox(checkBox){
  if (checkBox.checked) {
    setCookie("promoCash", "yes", null, "/");
  } else {
    setCookie("promoCash", "", null, "/");
  }
}

function quick_add_to_slip(outcome_id, price_description, price_id, price_decimal, price_format, deduction) {

	var tp = 0;
  	if ($J("#sp" + outcome_id).val() == "true") {
  		tp = 1;
	}
	price_id_tmp = price_id;
	if (price_id == "") {
      price_id_tmp = 0;
    }

	singleSelections = [];
	multipleSelections = [];
	remove_added_bets_mark(null);
	
	singleSelections[0]={ "outcome_id": outcome_id ,"price_id": price_id_tmp, "price_decimal": price_decimal, 
	                      "stake": 0, "old_price": price_description, "tp": tp, "p_taken": 0, "deduction": deduction, 
	                      "price_format": price_format};

	save_single_betslip(singleSelections);
	setCookie("completedBets", "", null, "/");
	setCookie("bsMultiples", "", null, "/");
	
	$J('#betSlip').load("/"+escape(VC_SITE)+"/"+escape(VC_LANG)+"/betslip/show_slip_from_success", function(){readyBetslip();});
}

function add_to_slip(outcome_id, price_description, price_id, price_decimal, price_format, currency_code, update_multiples, place_terms_deduction, outcome_description, event_description, ew, sp, market_description) {

  // Check not already in slip
  for (s = 0; s < singleSelections.length; s++) {
    if (parseInt(singleSelections[s].outcome_id) == parseInt(outcome_id)) {
		remove_from_slip(VC_SITE, VC_LANG, singleSelections[s].outcome_id, singleSelections[s].price_id)
      return;
    }
  }
  
  if (singleSelections.length >= 20)
  {
    alert("You have reached the maximum number of selections (20).".t())
    return;
  }
  
	// If the error box is present, remove it
	if ($J('#tipBetBox').length > 0) {
		$J("#tipBetBox").remove();
	}

  var tp = 0;
  if (sp === true || sp == "true") {
    tp = 1;
  }
  
  // if we don't have the place terms, we can assume we don't have the rest either
  if (typeof(place_terms_deduction) == "undefined") {
    var place_terms_deduction = $J('#place_terms_deduction' + outcome_id).val();
	  var outcome_description   = $J("#outcome_description"   + outcome_id).val();
    var event_description     = $J('#event_description'     + outcome_id).val();
	  var market_description    = $J('#market_description'    + outcome_id).val();
    var ew                    = $J("#ew"                    + outcome_id).val();
    if ($J("#sp" + outcome_id).val() == "true") {
      tp = 1;
    }
  }

  // Checking if the user is seeing the default betslip box
	if (($J("#betSlipConfirmation").length > 0)) {
	  quick_add_to_slip(outcome_id, price_description, price_id, price_decimal, price_format, place_terms_deduction);
	  return false;
	} else if (!($J("#betSlipMain").length > 0)) {
	  alert("finish procedure message".t());
	  return false;
    }
    // Default is true, Forecast will only update after adding all.
    if (update_multiples == null) {
        update_multiples = true;
    }

  reloadVariables();

  $J(singlesContainer).removeClass("hide");
  
  if (price_id == "") {
    price_id = 0;
  }

  var template_parts = [];
  template_parts.push([
    "<fieldset id='betBox#{outcome_id}'>",
      "<div class='singleBet'>",
      "<div class='singleHeader'>",
      "<a title='#{remove_title}' href='#' onclick=\"remove_from_slip(escape(VC_SITE), escape(VC_LANG), '#{outcome_id}', '#{price_id}')\" class='removeSingle'></a>",
      "<h3>#{event_description}</h3>",
      "</div>",
      "<p class='betPrice'>"
  ]);
    
  if (tp > 0) 
  {
  	if (price_description.toUpperCase() != "SP") 
  	{
  	  template_parts.push([
	  	  "<select onchange='updateOutcomeTakePrice(#{outcome_id}); startPriceChange(\"#{outcome_id}\", \"SP\");saveBetslip();' name='odds#{outcome_id}' id='odds#{outcome_id}' class='odds'>",
	  	    "<option value='#{price_decimal}'>#{price_description}</option>",
	  	    "<option value='SP'>SP</option>",
	  	  "</select>"
	    ]);
	  } 
	  else
	  {
	    template_parts.push([
	  	  "<input type='hidden' name='odds#{outcome_id}' id='odds#{outcome_id}' value='#{price_decimal}'>",
	  	  "<span class='odds'>#{price_description}</span>"
	  	]);
	  }	  
  } 
  else
  {
    template_parts.push([
  	  "<input type='hidden' name='odds#{outcome_id}' id='odds#{outcome_id}' value='#{price_decimal}'>",
	    "<span class='odds'>#{price_description}</span>"
	  ]);
  }

  template_parts.push([
      "</p>",
    "<p class='betSelection'><label class='fOdds' for='odds#{outcome_id}'>#{outcome_description}</label><br>",
	"<label class='fMarket' for='market#{outcome_id}'>(#{market_description})</label></p>",
    "<p class='betStake'>",
    "<span class='betEW'>"
  ]);
  
  if (ew === true || ew == "true") 
  {
    template_parts.push([
      "<label for='eachWay#{outcome_id}'>EW</label>",
      "<input id='eachWay#{outcome_id}' name='eachWay#{outcome_id}' value='yes' class='fEachWay' alt='Each Way' onclick='saveEachWay(this, #{outcome_id});' type='checkbox'/>"
    ]);
  }
  
  template_parts.push([
      "</span>",
      "<label for='stake#{outcome_id}'>#{stake_text} #{currenty_code}</label>",
        "<input type='text' value='0.00' size='5' onblur='stakeOnBlur(this); checkMinStakeSingles(this, #{outcome_id});' onfocus='onFocusStake(this);' onkeyup=\"validateStake(this); updateStakeAndTotals(#{outcome_id}, this, 's');\" name='stake#{outcome_id}' maxlength='8' id='stake#{outcome_id}'/>",
      "</p>",
      "</div>",
      "<input type='hidden' value='#{place_terms_deduction}' name='deduction#{outcome_id}' id='deduction#{outcome_id}' />"
  ]);
  
  template_parts.push([
      "<div class='minStake hide' id='minStake#{outcome_id}'>",
      "<p>",
      "<label for='minstake'>#{min_stake} " + getMinStakeSingles() + "</label>",
      "</p>",
      "</div>",
	  "</fieldset>"
  ]);

  var template = new Template(template_parts.flatten().join("\n"))
  var html = template.evaluate({
    outcome_id:             outcome_id,
    outcome_description:    outcome_description.escapeHTML(),
    price_decimal:          price_decimal,
    price_description:      price_description,
    currenty_code:          currency_code,
    place_terms_deduction:  place_terms_deduction,
    event_description:      event_description.escapeHTML(),
    price_id:               price_id,
    remove_title:           'Remove this bet from betslip'.t(),
    stake_text:             'Stake'.t(),
	min_stake:				'The minimum stake is'.t(),
	market_description:     market_description.escapeHTML()
  });

  $J(singlesContainer).append(html);

  singlesContainer.style.height = null;
  mark_added_bets(outcome_id);

  singleSelections[singleSelections.length] = {
    "outcome_id":     outcome_id,
    "price_id":       price_id, 
    "price_decimal":  price_decimal, 
    "stake":          0, 
    "old_price":      price_description, 
    "tp":             tp, 
    "p_taken":        0, 
    "deduction":      place_terms_deduction, 
    "price_format":   price_format
  };
    
  if($J("#betSlipToggle").hasClass('openBetSlip')) {
    betSlipOpen();
  }
  
  if (update_multiples && singleSelections.length > 1) { 
    updateMultiples(); 
  }
  
  saveBetslip();
  reloadCounter();
  check_height();
  update_inrunning();
}

function updateMultiples() {
  singlesJSON = singleSelectionsJSON();
  $J("#betSlipMultiples").show();
  //$J("#betSlipMultiples h3").addClass("loading");

  if (singleSelections.length > 0) {
  	if (singleSelections.length > 1) {
		blockRegion.create('betSlipMultiples');
	}
    saveMultiplesBetslip();   
    
    new Ajax.Request('/'+escape(VC_SITE)+'/'+escape(VC_LANG)+'/betslip/load_multiples', {
      
      parameters: { "singles_selections": singlesJSON }, 
      
      onSuccess: function(transport) {
        var json = transport.responseText.evalJSON();
        var multi_str = render_multiple(json);
        $J("#multiplesDiv").html(multi_str);
        $J("#betSlipMultiples h3").removeClass("loading");
        saveMultiplesBetslip();
      },
      
      // runs even if there's an error
      onComplete: function() {
        //$J("#betSlipMultiples h3").removeClass("loading");
		blockRegion.remove('betSlipMultiples');
      }
    });
  }
}

function singleSelectionsJSON() {
  var price_id_tmp;
  // Prepare call for JSON Multiples
  str = '';
  for (s = 0; s < singleSelections.length; s++) {
       if (singleSelections[s].price_id == "") {
         price_id_tmp = 0;
       } else {
         price_id_tmp = singleSelections[s].price_id;
       }
       str += "{\"outcome_id\": "+singleSelections[s].outcome_id+",\"price_id\": "+price_id_tmp+",\"price_decimal\": "+ singleSelections[s].price_decimal+",\"stake\": " + singleSelections[s].price_decimal+",\"tp\": "+singleSelections[s].tp+",\"f\": "+singleSelections[s].price_format+"}";
       if (s < (singleSelections.length-1)){ str += ","; }
  }
  return "[" + str + "]";
}

function render_multiple(multi_array) {
  multipleSelections = [];
  var params = {};
  var template_parts = [];
      
  if (multi_array.length > 0 ) {
   $J("#betSlipMultiples").show();
    template_parts.push([
     "<table class='multiplesTable'>",
          "<tr>",
            "<th>"+"Bet Type".t()+"</th>",
            "<th>"+"Stake".t()+"</th>",
            "<th>"+"E/W".t()+"</th>",
          "</tr>"
    ]);
    
    for (m = 0; m < multi_array.length; m++) 
    {
      template_parts.push([
        "<tr>",
          "<td>" + multi_array[m].description + " / " +  multi_array[m].multiplicity +"</td>",
          "<td>",
            "<input type='text' value='0.00' size='5' onkeyup='validateStake(this); updateStakeAndTotals("+multi_array[m].winBetTypeId+", this, \"m\");' onblur='stakeOnBlur(this); checkMinStakeMultiples(this, " + multi_array[m].winBetTypeId + ");' onfocus='onFocusStake(this);' name='unitStake"+multi_array[m].winBetTypeId+"' maxlength='8' id='unitStake"+multi_array[m].winBetTypeId+"'/>",
          "</td>",
          "<td>"
      ]);
      
      if (multi_array[m].EW == true) 
      {
        template_parts.push([
          "<input type='checkbox' value='yes' id='tEachWay"+multi_array[m].winBetTypeId+"' name='tEachWay"+multi_array[m].winBetTypeId+"' onclick='saveMultipleEachWay(this,"+multi_array[m].winBetTypeId+");' class='fEachWay' alt='"+"Each Way".t()+"' />"
        ]);
      }
      
      template_parts.push([
            "<input type='hidden' value='" + multi_array[m].multiplicationFactor + "' name='multFactors_"+ multi_array[m].winBetTypeId + "' id='multFactors_"+ multi_array[m].winBetTypeId + "'/>",
            "<input type='hidden' value='" + multi_array[m].ewMultiplicationFactor + "' name='ewMultFactor"+ multi_array[m].winBetTypeId + "' id='ewMultFactor"+ multi_array[m].winBetTypeId + "' />",
          "</td>",
        "</tr>"
      ]);
	  
	  template_parts.push([
	  "<tr>",
        "<td colspan='3' class='minStake'>",
          "<div class='minStake hide' id='minStake" + multi_array[m].winBetTypeId + "'>",
             "<label for='minstake'>#{min_stake} " + getMinStakeMultiples() + "</label>",
          "</div>",
        "</td>",
     "</tr>"
	 ]);

  	  var hideReturn = 0;
  	  if (multi_array[m].forecast || multi_array[m].tricast || multi_array[m].reverse || multi_array[m].combination) 
  	  {
  	  	hideReturn = 1;
  	  }
      multipleSelections[m]={ "bet_type_id": multi_array[m].winBetTypeId, "stake": 0, "each_way": 0, "multiFactor": multi_array[m].multiplicationFactor, "ewMultiFactor": multi_array[m].ewMultiplicationFactor, "multiplicity": multi_array[m].multiplicity, "hide_return": hideReturn};
      
    }
    
    template_parts.push([
     "</table>"
	]);
	
	var template = new Template(template_parts.flatten().join("\n"))
    var html = template.evaluate({
    	min_stake:  'The minimum stake is'.t()
    });
	
  } else {
    $J("#betSlipMultiples").hide();
  }
  
  updateTotals();
  return html;
}

function trim(str) {
    return str.replace(/^\s+|\s+$/g,"");
}

function populateBetslip() {
	singleSelections    = parseSinglesCookie(getCookie("bsSingles"));
	multipleSelections  = parseMultiplesCookie(getCookie("bsMultiples"));
	if (singleSelections.length == 0) {
		betSlipClose();
	}
}

function parseSinglesCookie(cookie_data) {
  if (!cookie_data || cookie_data == "") {
    return [];
  }
  var entry_array = cookie_data.split("|");
  return entry_array.collect(function(entry){
    var item = entry.split(":");
    return {
      outcome_id:      item[0],              // o
      price_id:        item[1],              // p
      price_decimal:   item[2],              // d
      stake:           item[3],              // s
      each_way:        item[4],              // e
      old_price:       item[5],              // l
      tp:              item[6],              // k
      p_taken:         item[7],              // t
      deduction:       item[8],              // w
      price_format:    item[9]               // f   
    };
  });
}

function parseMultiplesCookie(cookie_data) {
  if (!cookie_data || cookie_data == "") {
    return [];
  }
  var entry_array = cookie_data.split("|");
  return entry_array.collect(function(entry){
    var item = entry.split(":");
    return {
			bet_type_id:    item[0],         // i
			stake:          item[1],         // s
			each_way:       item[2],         // e
			multiFactor:    item[3],         // m
			ewMultiFactor:  item[4],         // w
			multiplicity:   item[5],         // x
			hide_return:    item[6]          // h
    };    
  });
}

function saveEachWay(obj, outcome_id) {
  if (obj.checked) {
      $J("#ewmult_"+outcome_id).val('2');
  } else {
      $J("#ewmult_"+outcome_id).val('1');
  }
  saveBetslip();
  updateTotals();
}

function saveMultipleEachWay(obj, bet_type_id) {
  if (obj.checked) {
      $J("#ewmultMult_"+bet_type_id).val('2');
  } else {
      $J("#ewmultMult_"+bet_type_id).val('1');
  }
  saveMultiplesBetslip();
  updateTotals();
}

// Cycle selections with take price and update price before submit
function prepareTakePrices() {
	for (s = 0; s < singleSelections.length; s++) {
		if ((singleSelections[s].tp == 1) && ($J("#odds" + singleSelections[s].outcome_id).val()== "SP")) {		
			singleSelections[s].price_id = 0;
			singleSelections[s].price_decimal = 0;
			singleSelections[s].old_price = "SP";
		}
	}
}

function updateOutcomeTakePrice(outcome_id) {
	for (s = 0; s < singleSelections.length; s++) {
		if (singleSelections[s].outcome_id == outcome_id) {
			if ($J("#odds" + outcome_id).val() == "SP") {
				singleSelections[s].p_taken = 1;
			} else {
				singleSelections[s].p_taken = 0;
			}
		}
	}
}

function loadError(message) {
  if (message == null) {
    message = "betslip error message".t();
  }
  $J("#tipBetBox").html("<span>"+message+"</span>");
  $J("#tipBetBox").slideUp("fast");
  $J("#tipBetBox").removeClass("hide");
  $J("#tipBetBox").slideDown("slow");
}

function readyBetslip() {
	reloadVariables();
	initBetslip();
	populateBetslip();
	mark_bets_on_coupon();
	check_height();
	check_height_multiples();
	updateTotals();
	reloadCounter();
	place_bets_remove_loading();	

	// Add bets from hashtag see _betslip partial.
	add_to_betslip_from_hashtag();
  
  // add bets from querystring
  add_to_betslip_from_querystring();
  
  // not submitting any more
  submitting_betslip = false;
  
   
}

function resetBetslip() {
	var c = getCookie("keepBets");
	if ((c == null) || (c == "")) {
		singleSelections = [];
		multipleSelections = [];
		setCookie("bsSingles", "", null, "/");
		setCookie("bsMultiples", "", null, "/");
	} else {
		resetEW();
	}	
	setCookie("promoCash", "", null, "/");
}

function resetEW() {
	for (s = 0; s < singleSelections.length; s++) {
		s.each_way = 0;
	}
	saveBetslip();
	for (m = 0; m < multipleSelections.length; m++) {
		m.each_way = 0;
	}
	saveMultiplesBetslip();
}

// Function to work out global totals
function updateTotals() {
	var totalStakes = 0;
	var totalStakeSingles = 0;
	var totalStakeMultiples = 0;
	var totalReturnsSingles = 0;
	var totalReturnsMultiples = 0;
	var totalReturns = 0;
	var spBet = false;
	
	//Singles
	if (singleSelections.length > 0) {
		for (s = 0; s < singleSelections.length; s++) {
			if ((parseFloat(singleSelections[s].stake) > 0 && parseInt(singleSelections[s].price_id) == 0) || (singleSelections[s].p_taken == 1)) {
				spBet = true;
			}
			if (singleSelections[s].each_way > 0) {
				totalReturnsSingles += parseFloat(singlesCalculation(singleSelections[s].stake, singleSelections[s].price_decimal, singleSelections[s].deduction));
				totalStakeSingles += parseFloat(singleSelections[s].stake * 2);
			} else {
				totalReturnsSingles += parseFloat(singlesCalculation(singleSelections[s].stake, singleSelections[s].price_decimal));
				totalStakeSingles += parseFloat(singleSelections[s].stake);
			}
		}	
	}
	// Multiples
	if (multipleSelections.length > 0) {
		for (m = 0; m < multipleSelections.length; m++) {
			if (multipleSelections[m].each_way > 0) {
				totalReturnsMultiples += parseFloat(multiplesCalculation(multipleSelections[m].stake, multipleSelections[m].ewMultiFactor));
				totalStakeMultiples += parseFloat(multipleSelections[m].stake) * parseFloat(multipleSelections[m].multiplicity) * 2;
			} else {
				var stake = parseFloat(multipleSelections[m].stake) * parseFloat(multipleSelections[m].multiplicity);
				totalReturnsMultiples += parseFloat(multiplesCalculation(stake, multipleSelections[m].multiFactor));				
				totalStakeMultiples += stake;
			}
			if (parseInt(multipleSelections[m].hide_return) > 0) {
				spBet = true;
			}
		}	
	}
	
	// If only multiples, check for SP in singles
	if (totalStakeMultiples > 0 && !spBet) {
		for (s = 0; s < singleSelections.length; s++) {
			if (parseInt(singleSelections[s].price_id) == 0 || singleSelections[s].p_taken == 1) {
				spBet = true;
			}
		}
	}
	
	totalStakes = parseFloat(totalStakeSingles) + parseFloat(totalStakeMultiples);
	totalReturns = parseFloat(totalReturnsSingles) + parseFloat(totalReturnsMultiples);
	
	if ($J("#totalStake").length > 0) {
		$J("#totalStake").text(totalStakes.toFixed(2));
	}
	if (getCookie("promoCash") != null && getCookie("promoCash") == "yes" ) {
		totalReturns -= totalStakes; 
	}
	if (spBet) {
		$J("#totalMult").text("N/A");
	} else {
		$J("#totalMult").text(totalReturns.toFixed(2));
	}
}

// Function that works out Returns for individual selection
function singlesCalculation(stake, odds, deduction) {
	if (deduction == null) {
		return stake*odds;
	}
	return stake*((parseFloat(odds)+1)+(parseFloat(odds)-1)/parseFloat(deduction));
}

// Function that works out Returns for multiple selections
function multiplesCalculation(stake, factor) {
	return stake*factor;
}

// Function which updates the stake in the list and works out totals
function updateStakeAndTotals(id, stake, betType) {
	if (betType == 's') {
		for (s = 0; s < singleSelections.length; s++) {
			if (singleSelections[s].outcome_id == id) {
				singleSelections[s].stake = stake.value;
				saveBetslip();
				break;
			}
		}
	} else if (betType == 'm') {
		for (m = 0; m < multipleSelections.length; m++) {
			if (multipleSelections[m].bet_type_id == id) {
				multipleSelections[m].stake = stake.value;
				saveMultiplesBetslip();
				break;
			}
		}
	}
	updateTotals();	
}

// this is a bit nasty, but easiest way to stop double submissions
// without rebuilding the JS for the betslip
var submitting_betslip = false;
function prepareAndSubmitBetslip() {
  if (submitting_betslip) {
    return false;
  }
  submitting_betslip = true;
  prepareTakePrices();
  saveBetslip();
  saveMultiplesBetslip();  
  return true;
}

// Now the betslip is loaded with an ajax call. See LayoutAjaxComponentsController.
// $J(document).ready(function(){
//    readyBetslip();
// });

/* Add to betslip from an Url HashTag */
function add_to_betslip_from_hashtag() {
  var hash=location.hash;
  var params;
  if (hash){
    params = hash.split("|");
    if (params.length == 4) {
      add_to_slip(params[0].replace("#",''),
        params[1],
        params[2],
        params[3],
        VC_USER_PRICE_FORMAT,
        VC_USER_CURRENCY_SYMBOL, 
				true);    
    }
  }    
}

function validateStake(stake) {

	var currentValue = stake.value;
	var lastChar = currentValue.charAt(currentValue.length-1);

	if (isNaN(currentValue)) {
		stake.value = currentValue.substring(0, currentValue.length - 1);
	}
	if (currentValue == ".") {
		stake.value = "0.";
	}
} 

function checkMinStakeSingles(stake, outcomeId) {
	if ((parseFloat(stake.value) > 0) && (parseFloat(stake.value) < getMinStakeSingles())) {
      $J("#minStake"+outcomeId).slideDown('fast');
	} else {
		$J("#minStake"+outcomeId).slideUp('fast');
	}
}

function checkMinStakeMultiples(stake, winTypeId) {
	if ((parseFloat(stake.value) > 0) && (parseFloat(stake.value) < getMinStakeMultiples())) {
      $J("#minStake"+winTypeId).slideDown('fast');
	} else {
		$J("#minStake"+winTypeId).slideUp('fast');
	}
}

function getMinStakeSingles() {
	return parseFloat(document.getElementById('minStakeSingles').value).toFixed(2);	
}

function getMinStakeMultiples() {
	return parseFloat(document.getElementById('minStakeMultiples').value).toFixed(2);	
}

function acceptChange(typeName, selectionId, betType) {
	var stakeBox = 'stake';
	if (betType == 'm') { stakeBox = 'unitStake'; }
	
	$J('#' + typeName + selectionId).click();
	$J('#betAmend' + selectionId).slideUp('fast');
	$J("#accepted"+selectionId).slideDown('fast');
	updateStakeAndTotals(selectionId, $J('#' + stakeBox + selectionId).val(), betType);
	removeErrorBox();
	flashButton();
}

function flashButton() {
	for (i = 0; i < 3; i++) {
		$J(".placeBet").fadeTo("fast", 0.4);
		$J(".placeBet").fadeTo("fast", 1.0);
	}
}

function removeErrorBox() {
	hideError = true;
	for( i=0; i < ($J(".accept_bet").size()); i++){ 
		if (!$J(".accept_bet")[i].checked) { 
			hideError = false; 
		}
	}
	if (hideError) {
		$J('#tipBetBox').slideUp('fast');
	}
}

function parse_querystring() {
  var qs = location.search.replace("?", "");
  var pairs = qs.split("&");
  var params = {};
    
  for (var i = 0; i < pairs.length; i++) {
    kv = pairs[i].split("=");
    params[kv[0]] = unescape(kv[1]);
  }
  
  return params;
}

var added_from_qs = false;
function add_to_betslip_from_querystring() {
  if (added_from_qs)
  {
    return;
  }
  added_from_qs = true;
  
  var qs = parse_querystring();

  if (qs != undefined) {
    if ((qs['outcome_id'] != undefined) && 
        (qs['price_description'] != undefined) && 
        (qs['price_id'] != undefined) &&
        (qs['price_decimal'] != undefined)) {
        // add_to_slip(outcome_id, price_description, price_id, price_decimal, price_format, currency_code, update_multiples)
        add_to_slip(
          qs['outcome_id'],
          qs['price_description'],
          qs['price_id'],
          qs['price_decimal'],
          VC_USER_PRICE_FORMAT,
          VC_USER_CURRENCY_SYMBOL,
          true
        );
    }
  }
}

function update_inrunning() {
  var outcome_ids = []
  for (s = 0; s < singleSelections.length; s++) {
     outcome_ids.push(singleSelections[s].outcome_id);
   }
   jQuery.inRunning.update_bets(outcome_ids);
}

function save_single_betslip(singles) {
  var separator = ""
  var cookieData = ""
  // Do Singles
  for (s = 0; s < singles.length; s++) {
      var entry = singles[s].outcome_id + ":" +                                                 // o
                  singles[s].price_id + ":" +                                                   // p
                  singles[s].price_decimal + ":" +                                              // d
                  singles[s].stake + ":" +                                                      // s
                  singles[s].each_way + ":" +                                                   // e
                  singles[s].old_price + ":" +                                                  // l
                  singles[s].tp + ":" +                                                         // k
                  singles[s].p_taken + ":" +                                                    // t
                  singles[s].deduction + ":" +                                                  // w
                  singles[s].price_format                                                       // f      
      cookieData += separator + entry
      separator = "|"
  }
  setCookie("bsSingles", "", null, "/");
  setCookie("bsSingles", cookieData, null, "/");
}

function save_multiples_betslip(multiples) {
    var separator = ""
    var cookieData = ""
    // Do Multiples
    for (m = 0; m < multiples.length; m++) {
  		var entry = multiples[m].bet_type_id + ":" +                          // i
			            multiples[m].stake + ":" +                                // s
				          multiples[m].each_way + ":" +                             // e
				          multiples[m].multiFactor + ":" +                          // m
				          multiples[m].ewMultiFactor + ":" +                        // w
				          multiples[m].multiplicity + ":" +                         // x
				          multiples[m].hide_return                                  // h
			 cookieData += separator + entry
       separator = "|"
    }
    setCookie("bsMultiples", "", null, "/");
    setCookie("bsMultiples", cookieData, null, "/");
}



function initBalance() {
    var btHide = $J("#memberDetails > .balance > a");
    //if(btHide.attr("title") == "hide")return;
    btHide.attr({title:"hide"});
    btHide.click(function () {
        var balance = $J("#memberDetails > .balance > span");
        if($J(this).attr('className') == "hideBalance"){
            /*balance.slideToggle();*/
            //$J("#memberDetails > .balance > span").addClass("hidden")
			$J("#memberDetails > .balance > span").hide();
            //$J(this).html("<img src='/images/show.gif' alt='Show Balance' />");
            $J(this).addClass("showBalance");
            $J(this).removeClass("hideBalance");
            $J("#balanceValue").css("width","100px")
    		//document.getElementById("balanceValue").style.width = "108px"
        }
        else if ($J(this).attr('className') == "showBalance"){
            /*balance.slideToggle();*/
            //$J("#memberDetails > .balance > span").removeClass("hidden")
            $J("#memberDetails > .balance > span").show();
            //$J(this).html("<img src='/images/hide.gif' alt='Hide' />");
            $J(this).addClass("hideBalance");
            $J(this).removeClass("showBalance");
            $J("#balanceValue").css("width","210px")
            //var widthBalanceValueContainer = document.getElementById("balanceValueContainer").offsetWidth;
			//widthBalanceValueTotal = widthBalanceValueContainer + 128;
			//document.getElementById("balanceValue").style.width = widthBalanceValueTotal + "px";    
        }
    });    
}
//$J(document).ready(function(){initBalance()});


var CouponSelections = Class.create({
  
  max: 20,
  
  initialize: function()
  {
    document.observe('click', this.clicked.bindAsEventListener(this));
  },
  
  clicked: function(e)
  {
    var element = e.element();
    
    if (element.nodeName != 'A')
    {
      return;
    }
    
    if (element.hasClassName('selectAll'))
    {
      this.select_all(element);
      e.stop();
    }
    else if (element.hasClassName('deselectAll'))
    {
      this.deselect_all(element);
      e.stop();
    }
    else if (element.hasClassName('showSelections'))
    {
      this.show(element);
      e.stop();
    }
  },
  
  checkboxes: function(element)
  {
    // a bit nasty
    // there's no common container class so just go up 2 divs
    // ideally should be able to be element.up('.wrapper') or something
    return element.up('div').up('div').select('input[type=checkbox]');
  },
  
  show: function(element)
  {
    var form = element.up('form'); 
    
    // check all checkboxes, not just the one in this box
    var num_checked = form.select('input[type=checkbox]').inject(0, function(acc, cb){
      return acc + (cb.checked ? 1 : 0);
    });
    
    if (num_checked === 0)
    {
      alert("Please choose at least one selection to view.".t());
      return;
    }
    else if (num_checked > this.max)
    {
      if (!confirm("Loading this many selections may take a while, are you sure you wish to continue?".t()))
      {
        return;
      }
    }

   form.submit();
  },
  
  deselect_all: function(element)
  {
    this.checkboxes(element).each(function(cb){
      cb.checked = false;
    });
  },
  
  select_all: function(element)
  {
    this.checkboxes(element).each(function(cb){
      cb.checked = true;
    });    
  }
  
});

document.observe('dom:loaded', function(){
  new CouponSelections();
});

/*
 * Refreshes the coupons with any new data every x seconds 
 *
 * The following may also be set:
 * CouponRefresh.basket_number
 * CouponRefresh.cache_version
 */
var CouponRefresh = Class.create({
  
  // delay between refresh in seconds
  interval: 5,
  
  // whether or not we're auto-updating
  autoupdate: true,
  
  // id of the DOM node containing the status to update
  status_container_id: 'updateStatus',
  
  // cache of coupon slider changes
  open_coupons: [],
  closed_coupons: [],
  
  // params to send with the request
  params: {},
  
  initialize: function(options)
  {
    Object.extend(this, options);
    
    this.status_container   = $(this.status_container_id);
    this.set_timer();
    
    // listen to the sliders
    document.observe('slider:toggled', this.slider_changed.bind(this));
    
    // listen to clicks so we can see if someone clicked 'refresh'
    document.observe('click', this.clicked.bind(this));
  },
  
  clicked: function(e)
  {
    var element = e.element();
    if (element.nodeName == 'A' && element.hasClassName('refreshCouponPrices'))
    {
      e.stop();
      this.refresh();
    }
  },
  
  set_timer: function()
  {
    if (this.autoupdate)
    {
      clearTimeout(this._timer);
      this._timer = setTimeout(this.refresh.bind(this), this.interval * 1000);
    }
  },
  
  refresh: function()
  {
    this.status_container.removeClassName("updateError");
    this.status_container.removeClassName("updateSuccess");
    this.status_container.update(priceUpdate);
    
    this.params["open_coupons[]"]   = this.open_coupons;
    this.params["closed_coupons[]"] = this.closed_coupons;    
    
    if (CouponRefresh.basket_number)
    {
      this.params['basket_number'] = CouponRefresh.basket_number;
      this.params['cache_version'] = CouponRefresh.cache_version;
    }
    
    new Ajax.Request(this.url, {
      asynchronous:true,
      evalScripts: true, 
      parameters: this.params,
      onSuccess: this.success.bind(this),
      onFailure: this.failure.bind(this)
    });
  },
  
  success: function()
  {
    this.status_container.addClassName("updateSuccess");
    this.status_container.update( priceUpdatedAt +this.time());
    this.set_timer();    
  },
  
  failure: function()
  {
    this.status_container.addClassName("updateError");
    this.status_container.update("Updating Failed "+this.time());    
    this.set_timer();    
  },
  
  // called if CouponRefresh.reorder_coupons is set to true during a refresh
  // go through each event and see if it has any ordering changes
  reorder: function()
  {
    $$('div.event').each(function(event){
      this.reorder_event_coupons(event);      
    }.bind(this));
  },
  
  // a slider has been toggled
  // update the open coupon ids
  slider_changed: function(e)
  {
    var coupon = e.memo.element.up('.coupon');
    if (!coupon)
    {
      return;
    }
    
    var id = coupon.id.gsub(/\D/, '');
    if (e.memo.state == 'opened')
    {
      this.open_coupons.push(id);
      this.remove_coupon_from_cache(id, this.closed_coupons);      
    }
    else
    {
      this.closed_coupons.push(id);
      this.remove_coupon_from_cache(id, this.open_coupons);
    }
  },
  
  remove_coupon_from_cache: function(id, cache)
  {
    for (var i=0; i<cache.length; i++)
    {
      if (cache[i] == id)
      {
        cache.remove(i);
        break;
      }
    }    
  },
  
  coupon_slider_statuses: function()
  {    
    if (this.coupon_status_cache.length === 0)
    {
      return 'none';
    }
    else
    {
      return this.coupon_status_cache;
    }
  },
  
  reorder_event_coupons: function(event)
  {  
    var event_id = event.id.gsub(/\D/, '');
    var refresh_container = $("refresh_container"+event_id);
    
    var positions = [];
    var coupons   = [];
    
    event.select('.coupon').each(function(coupon){
      var pos_str = coupon.classNames().find(function(cn){
        return cn.match(/pos_/);
      });
      
      if (pos_str)
      {
        coupons.push(coupon);
        positions.push(pos_str);
      }
    });
    
    // returns array per item of [string, coupon]
    var sorted = this.sort_positional(positions, coupons);

    // only reorder if the order has changed
    var sorted_positions = sorted.collect(function(x){ return x[0]; });
    
    var old_orders = positions.join('');
    var new_orders = sorted_positions.join('');
        
    if (new_orders == old_orders)
    {
      return;
    }

    // re-insert them into the container in the new order
    sorted.each(function(bits)
    {
      refresh_container.insert({bottom: bits[1]});
    });
  },
  
  time: function()
  {
    var d = new Date();  
    return this.pad(d.getHours()) + ":" + this.pad(d.getMinutes()) + ":" + this.pad(d.getSeconds());
  },
  
  pad: function(t)
  {
    if (parseInt(t, 0) < 10) 
    {
      t = "0"+t;
    }
    return t;    
  },
  
  // sorts an array of objects based on an array of positional strings 
  // 
  // IE: 
  // ["pos_2_0_3",
  // "pos_10_2_5",
  // "pos_1_0_4",
  // "pos_10_8_3",
  // "pos_1_0_3",
  // "pos_2_1_6",                    
  // "pos_1_1_3"]
  // 
  // to
  // 
  // ["pos_1_0_3",
  // "pos_1_0_4",
  // "pos_1_1_3",
  // "pos_2_0_3",
  // "pos_2_1_6",
  // "pos_10_2_5",
  // "pos_10_8_3"]
  sort_positional: function (strs, objects)
  {
    var sorter = [];

    strs.each(function(str, i){
      var parts = str.split('_');

      // get rid of the 'pos'
      parts.shift();

      // turn them into integers
      var positions = parts.collect(function(x){ return parseInt(x, 0); });

      sorter.push({
        str: str,
        object: objects[i],
        positions: positions
      });
    });

    var sorted = sorter.sort(function(a,b){
      var len = a.positions.length;
      for (var i=0; i<len; i++)
      {
        if (a.positions[i] < b.positions[i])
        {
          return -1;
        }
        else if (a.positions[i] > b.positions[i])
        {
          return 1;
        }
      }
      return 0;
    });

    return sorted.collect(function(x){ return [x.str, x.object]; });
  }
  
});

var blockRegion = {
    
    create:function(targetId){
        
        if($J("#" + targetId + " #blockRegion").length == 1)return;
        
        var preload = $('BlockRegion_preload');

        if(preload)preload.remove();

        var self = blockRegion;

        var target = $(targetId);

        var cursor = new Element('img',{id:"cursor", src:loading_image_path});
        
        cursor.setStyle({
            
            position:"absolute",
            
            top:(Math.min(screen.height/2, target.getDimensions().height/2) - 21) + target.positionedOffset().top + "px",
            
            left:(Math.min(screen.width/2, target.getDimensions().width/2) - 50) + target.positionedOffset().left + "px"
            
        })
        
        
        /************************************************************************************************
        | Creating Iframe
        *************************************************************************************************/
        var iframe = new Element('iframe', {id:"iBlockRegion", frameBorder:"0", src: "/blank.html"});
        iframe.setStyle({
            
            position:"absolute",
            
            top:target.positionedOffset().top + "px",
            
            left:target.positionedOffset().left + "px",
            
            width:target.getDimensions().width + "px",
            
            height:target.getDimensions().height + "px",
            
            filter: "alpha(Opacity=50)",
            
            overflow:"hidden"
            
        });
        
        /************************************************************************************************
        | Creating Block
        *************************************************************************************************/
        var block = new Element('div',{id:"blockRegion"});
        
        block.setStyle({
            
            position:"absolute",
            
            top:target.positionedOffset().top + "px",
            
            left:target.positionedOffset().left + "px",
            
            width:target.getDimensions().width + 1 + "px",
            
            height:target.getDimensions().height + "px",
            
            overflow:"hidden"
            
        });

        /*************************************************************************************************
        | Creating Timer
        *************************************************************************************************/
        var timer = new Element('div',{id:"betslipTimer", style:"display: none"});
        
        timer.setStyle({
            position:"absolute",

            top:(Math.min(screen.height/2, target.getDimensions().height/2) + 49) + target.positionedOffset().top + "px",

            left:"0",

            margin:"0px",

            padding:"13px 0px 0px 0px",

            width:"207px",

            textAlign: "center",

            overflow:"hidden",

            height:"200px"});
        
         /************************************************************************************************
        | Appending the objects
        *************************************************************************************************/
        // Temporary Approach to keep "Block Region" over other elements in the page
        $J(block).css("z-index", getNextHighestZindex(target));
        $J(cursor).css("z-index", getNextHighestZindex(target));
        $J(timer).css("z-index", getNextHighestZindex(target));
        
        target.insert(iframe);
        target.insert(block);
        target.insert(cursor);
        target.insert(timer);

    },
    
    remove:function(targetId){
        
        if($J("#" + targetId + " #blockRegion").length == 0)return;
        
        $J("#" + targetId + " #iBlockRegion").remove();
        
        $J("#" + targetId + " #blockRegion").remove();
        
        $J("#" + targetId + " #cursor").remove();

        $J("#" + targetId + " #timer").remove();	

        $(targetId).removeAttribute("blocked");
        
    },
    
    preload:function(){
        
        var cursor = new Element('img',{id:"BlockRegion_preload", src:loading_image_path, style:"display:none"});
        
        $$("body")[0].insert(cursor);
        
    }
    
} 
$J(document).ready(blockRegion.preload);




function selectAllCupons(obj, value){
    $J(obj).parent().parent().find('input').each(
        function(){this.checked = value}
    )
}

function submitAllSelections(formId){
    var anyChecked = false;
    $J("input[id^='marketing_checkbox_']").each(function() {
        if ($J(this).attr("checked")) {
          anyChecked = true;
        }
    });
    if (anyChecked) {
      $J("#"+formId).trigger("submit");
    }
}

function initHelpToolTips() {    
    $J("a[id^='helpToolTip'][title]").cluetip({
        splitTitle: '|', 
        arrows: true, 
        dropShadow: false,
        positionBy: 'auto',
        cluetipClass: 'jtip'});
		
	$J("a[id^='helpToolTip'][title]").mouseout(function(){
		$J("#cluetip").hide();
	});
	$J("a[id^='helpToolTip'][title]").mouseover(function(){
		$J("#cluetip").show();
	});
	$J(".formWrap").mouseover(function(){
		$J("#cluetip").hide();
	});
}

function initFormFieldsMask() {
  //$J("input[id^='deposit_limit_custom']").numeric();
}

function getNextHighestZindex(obj){
   var highestIndex = 0;
   var currentIndex = 0;
   var elArray = Array();
   if(obj){ elArray = obj.getElementsByTagName('*'); }else{ elArray = document.getElementsByTagName('*'); }
   for(var i=0; i < elArray.length; i++){
      if (elArray[i].currentStyle){
         currentIndex = parseFloat(elArray[i].currentStyle['zIndex']);
      }else if(window.getComputedStyle){
         currentIndex = parseFloat(document.defaultView.getComputedStyle(elArray[i],null).getPropertyValue('z-index'));
      }
      if(!isNaN(currentIndex) && currentIndex > highestIndex){ highestIndex = currentIndex; }
   }
   return(highestIndex+1);
}

//Disable form elements
jQuery.fn.disable = function(mode)
{
    var mode = mode || 'on';
    return this.each(function() {
    
        switch(mode)
        {
            case 'on': this.disabled = true; break;
            case 'off': this.disabled = false; break;
            case 'toggle': this.disabled = !this.disabled; break;
        }
        
    });
};


/*************************************************************************************************
| My money
******************************************************************************************	*******/
//open show modal dialog
function modalWin(link) {
  if (window.showModalDialog) {
    window.showModalDialog(link,"name","dialogWidth:900px; dialogHeight:900px;");
  } else {    
    window.open(link,'name','height=900','width=900','toolbar=no','directories=no','status=no','linemenubar=no','scrollbars=no','resizable=no','modal=yes');
  }
}
function modalWinGeneric(link, options){
	window.open(link,'name', options ? options : 'width=900,height=900,toolbar=no,directories=no,status=no,linemenubar=no,scrollbars=yes,resizable=no,modal=yes,top=0,left=0');
}
      
//check focus show modal window
function checkFocus() {
  if (window.navigator.appVersion.indexOf("MSIE")==-1) {
    if (modalWin!=null && !modalWin.closed) {
      self.blur();
      modalWin.focus();
    }
  }
}

//If this var is true the periodically call will still run
var check_refresh_var = true;

//This function will open a popup to the user select if he want to
//Keep updating the prices on coupon
function checkCouponRefresh(url) {
  toggleRefreshOnOff(false);
    $J.prompt('We noticed that you spent a long time on this page, do you want to disable the real-time update feature?'.t(),{ buttons: { Yes: true, No: false }, callback: function(v, m) {
  if (v) {
       $J.post(url, {disable: true}, function(){});
       toggleRefreshOnOff(false);
  } else {
    toggleRefreshOnOff(true);
  }
  }});
}

//Will show a message stoping the refresh
//used when the user is seeing a event or a meeting
//that has no markets or is suspended
function showMessageForRedirect(message, url) {
  toggleRefreshOnOff(false);
  $J.prompt(message, { callback: function() {window.location.href = url;} });
}


//This function will show a message using the impromptu plugin
function showMessage(message) {
  $J.prompt(message);
}

//This function will stop any current refresh
function toggleRefreshOnOff(run) {
  check_refresh_var = run;
}

/*
 * Function open site on a new window or same window couse target its not xhtml valid.
 * site - URL;
 * target - _blank or _self.
 * alert - true or false, 'true' or 'false'
 * Message to confirm if alert==true.
 */
function open_this_site(site, target, alert, message){
  function open_site_on(target, site){
    if(target == '_blank'){
      window.open(site);
    } else if(target == '_self') {
      window.location = site;
    }
  }

  if(alert=='true' || alert == true){
    if(confirm(message)){
      open_site_on(target, site);
    }
  } else {  
    open_site_on(target, site);
  }
}

function disable_separators(){
  var values=document.getElementById('country').options;
  for(var i=0;i<values.length;i++) {
    if(values[i].value=='-'){
      values[i].disabled='disabled';
    }
  }
  var values=document.getElementById('currency').options;
  for(var i=0;i<values.length;i++) {
    if(values[i].value=='-'){
      values[i].disabled='disabled';
    }
  }
}

function market_toggle_onclick(obj){
  if (obj.checked){
    document.getElementById('send_sms').disabled = false;
    document.getElementById('send_email').disabled = false;
    document.getElementById('send_phone').disabled = false;
  } else {
    document.getElementById('send_email').disabled ='disabled';
    document.getElementById('send_sms').disabled ='disabled';
    document.getElementById('send_phone').disabled ='disabled';
  }
}

/******************************************************************************************
| Function to show history game
*******************************************************************************************/
function gameHistoryOutOfFlash(url){
	var features="directories=no,location=no,menubar=no,resizable=no,scrollbars=yes,status=no,toolbar=no,width=550,height=640";
	window.open(url, "history", features);
}

function load_ajax_sport_page(sport){
  var url = $J(sport).attr("href"),
      title = $J(sport).attr("title");
  
  $J("#nav li.selected").toggleClass('selected');
	$J("#breadCrumb li:gt(1)").remove()	
	$J("#breadCrumb li").next().html("<span>Loading...</span>");
	$J('#mainContent').load(url + "?store_jumpback=1",{}, function(responseText, textStatus){
		if (textStatus == "success") {
			blockRegion.preload();
			initHelpToolTips();
			miniSlideFunc();
			$J("#breadCrumb li").next().html("<span>" + title + "</span>");
			$J(sport).parent().addClass('selected');
		} else {
			$J("#breadCrumb li").next().html("<span>Please try again later</span>");
		}
		$J(document).scrollTop(0);
	});
}

//Function to open game on popup
function openGamePopup(url, windowName, w, h, params) {
  // Turn of the balance refresher
	cashierDialogClosed();

  windowW = parseInt(w) < 745 ? 745 : parseInt(w)
  windowH = parseInt(h) + 114
  windowX = (screen.width / 2) - (windowW / 2)
  windowY = (screen.height / 2) - (windowH / 2)
  params = 'width=' + windowW + ',height=' + windowH + ',left=' + windowX + ',top=' + windowY + params;
  eval(windowName + " = window.open('" + url + "', '" + windowName + "', '" + params + "')");
  eval(windowName + '.focus()');
}

on_check_row_forecast = function (p, outcome_id,element) {

  var $ = $J
  
  try {
  
    if (p!='any') {
         if (!assert_at_least_one_selection(p, outcome_id, element))  { 
  
          //If the previous selections have not been made, do not allow selection
          $(element).attr('checked', "")
        } else if (there_is_outcomes_selected(p, outcome_id, element)){
  
          unselect_all(p, outcome_id, element);
          if (assert_at_least_one_selection(p, outcome_id, element)) {
            $(element).attr('checked', "checked");
          } else {
            $(element).attr('checked', "");          
          }
        } else {     
          if (p == '1'){
  
            // Remove all selections if the user click to uncheck.
            if (!$(element).attr('checked')) {
  
             unselect_all(p, outcome_id, element);
             return false;
            }
          }

          unselect_for_a_position_and_outcome_and_any(p, outcome_id, element);         
          if ($(element).attr('checked')) {
            $(element).attr('checked', "")
          } else {
            $(element).attr('checked', "checked");
          }
        }
        
     } else {

       unselect_all_places(element);   
           
       if (count_any_type_selecteds(element) > 6) {
         $(element).attr('checked', "");
         alert("Sorry, maximum number of selections for a Combination Forecast/Tricast is 6.".t());
       }
       
    }
    
  } catch(e){
  
    alert(e);
    
  }
}

count_any_type_selecteds = function(element) {
   var $ = $J
   var count = 0;
   $(element).parent().parent().parent().parent().find('.type_any').each(function(i,e){
     if ($(e).attr('checked')) {
       count = count + 1
     }
   })
   
   return count;
}


unselect_all_places = function(element) {
   var $ = $J
   $(element).parent().parent().parent().parent().find('.type_place').each(function(i,e){
     $(e).attr('checked', "");
   })
}

there_is_outcomes_selected = function(p, outcome_id, element) {
  var $ = $J

  var checkeds = 0
  $(element).parent().parent().parent().parent().find('.outcome_' + outcome_id).each(function(i,e){
    if ($(e).attr('checked') && e.id != element.id) {
      checkeds = checkeds + 1
    }
  })

  if (checkeds==0) {
    return false;
  } else {
    return true;
  }
}

/* validate the previous selections to ensure they have been selected in the correct order
  e.g. If a checkbox from column 2 is selected at least 1 checkbox from column 1 has been selected, 
       If a checkbox from column 3 is selected, then at least one checkbox from column 1 and column 2 have been selected 
*/
assert_at_least_one_selection = function(p, outcome_id, element) {
    var $ = $J
    
    var previous_p = false
    
    if (p == '2') var previous_p = ['1']
    
    if (p == '3') var previous_p = ['1','2']
    
    var assert_at_least_one_selection = true
    
    if (previous_p) {
      previous_p.each(function(i){
        if( !assert_one_selection(i, $(element).parent().parent().parent().parent()) ) {
          assert_at_least_one_selection = false
        }
      })
    }
    return assert_at_least_one_selection;
}    
    
unselect_for_a_position_and_outcome_and_any = function (p, outcome_id, element){
        var $ = $J

        $(element).parent().parent().parent().parent().find('.position_' + p).each(function(i,e){
          $(e).attr('checked', "");
        })
        
        $(element).parent().parent().parent().parent().find('.position_any').each(function(i,e){
          $(e).attr('checked', "");
        })
        
        $(element).parent().parent().parent().parent().find('.outcome_' + outcome_id).each(function(i,e){
          $(e).attr('checked', "");
        }) 
}

unselect_all = function (p, outcome_id, element){
        var $ = $J

        $(element).parent().parent().parent().parent().find('.position').each(function(i,e){
          $(e).attr('checked', "");
        })

}

assert_one_selection = function(p, element){

  var $ = $J
  
  var checkeds = 0

  $(element).find('.position_' + p).each(function(i,e){
    if ($(e).attr('checked')) {
      checkeds = checkeds + 1
    }
  })
  
  if (checkeds>0) {
    return true;
  } else {
    return false;
  }
  
}

function submitForecastBets() {
    var isTricast = true;

    var selections = {
        "first": document.getElementsByName('1'),
        "second": document.getElementsByName('2'),
        "third": document.getElementsByName('3'),
        "any": document.getElementsByName('any')};

    var toPlace = new Array();

    if (selections["third"].length == 0) {isTricast = false;}
        
	// Disable normal racecard selections	
	disableCouponSelections(selections["first"], toPlace);	
    // Cycle Selections to and add checked options	
    cycleSelections(selections["first"], toPlace);
    cycleSelections(selections["second"], toPlace);
    if (isTricast) { cycleSelections(selections["third"], toPlace); }
    cycleSelections(selections["any"], toPlace);

    if (toPlace.length == 0) {
        alert("Please make some selections".t());
    } else {
        for (var c = 0; c < toPlace.length; c++) {
            add_to_slip(
				toPlace[c].outcome_id,
                toPlace[c]["price_description"],                
                toPlace[c]["price_id"],
                toPlace[c]["price_decimal"],
                toPlace[c]["price_format"],
                toPlace[c]["user_currency"],
				false);
        }
        updateMultiples();
    }        
}

function disableCouponSelections(checkBoxList, toPlace) {
    for (var c = 0; c < checkBoxList.length; c++) {
        var selectionId = checkBoxList[c].id.substring(0, checkBoxList[c].id.length - 2);
        remove_from_slip(null, null, selectionId, '0');
    }
}

function cycleSelections(checkBoxList, toPlace) {
    for (var c = 0; c < checkBoxList.length; c++) {
        if (checkBoxList[c].checked == true) {
             var split = checkBoxList[c].value.split("::");
             var outcome = {
                 "outcome_id": split[0],
                 "price_description": split[1],
                 "price_id": split[2],
                 "price_decimal": split[3],
                 "price_format": split[4],
                 "user_currency": split[5]
             }
             
             toPlace[toPlace.length] = outcome;
        }
    }
}

// Populates the forecast coupon with selections in the betslip
function populateForecastCoupon() {
    /*var selections = {
        "first": document.getElementsByName('1'),
        "second": document.getElementsByName('2'),
        "third": document.getElementsByName('3'),
        "any": document.getElementsByName('any')};

    var pointer = 0;

    for (var s = 0; s < singleSelections.length; s++){

    }*/
    /* TODO */
}

var MediaSelectBox = Class.create({
  
  popup_config: {
    width:      100,
    height:     100,
    status:     'no',
    toolbar:    'no',
    location:   'no',
    menubar:    'no',
    resizable:  'no',
    scrollbars: 'yes' 
  },
  
  initialize: function(element, popup_config)
  {
    Object.extend(this.popup_config, popup_config);    
    
    this.element    = $(element);
    this.click_zone = this.element.down('span');
    this.options    = this.element.down('ul');    
    
    this.build_popup_string();
    
    this.click_zone.observe('click', this.clicked.bindAsEventListener(this));
    this.options.observe('click', this.option_clicked.bindAsEventListener(this));
    document.observe('mediaselect:show', this.other_shown.bindAsEventListener(this));
  },
  
  clicked: function(e)
  {
    this.showing ? this.close() : this.open();      
    e.stop();
  },

  document_clicked: function(e)
  {
    if (this.showing)
    {
      this.close();
    }
  },
  
  option_clicked: function(e)
  {
    e.stop();
        
    var element = e.element();
    if (element.nodeName != 'A')
    {
      return;
    }
    
    var url = element.href;

    // This handles the "loading..." link. We don't want to open a popup.
    if (url.indexOf('#nolink') > -1)
    {
      return;
    }
    if (element.hasClassName('same_window'))
    {
      window.location = url;
    }
    else
    {
      combo_id = element.parentNode.parentNode.parentNode.id;
      window.open(url, combo_id, this.popup_config_string);      
    }
    
    this.close();
  },
  
  open: function()
  {     
    this._document_click_handler = this.document_clicked.bindAsEventListener(this);
    document.observe('click', this._document_click_handler);
    
    this.options.show();
    this.showing = true;    
    
    // fire an event so any other selects can close
    document.fire('mediaselect:show', {select: this});
  },
  
  close: function()
  {
    this.options.hide();
    this.showing = false;
    document.stopObserving('click', this._document_click_handler);    
  },
  
  other_shown: function(e)
  {
    if (this.showing && e.memo.select != this)
    {
      this.close();
    }
  },
  
  build_popup_string: function()
  {
    var strs = [];
    $H(this.popup_config).each(function(pair){ strs.push(pair.key+'='+pair.value); });
    this.popup_config_string = strs.join(',');
  }

});

var VideoSelectBox = Class.create(MediaSelectBox, {
  
  open: function($super)
  {
    $super();
    this.load();
  },
  
  load: function()
  {
    this.options.update('<li class="loading"><a href="#">' + 'Loading...'.t() + '</a></li>');
    
    var url = "/"+VC_SITE+"/"+VC_LANG+"/video_streaming/update_media_bar";
    new Ajax.Request(url, {
      method: 'post',
      onSuccess: this.data_loaded.bind(this)
    });
  },
  
  data_loaded: function(transport)
  {
    this.options.update(transport.responseText);
  }
  
});

document.observe('dom:loaded', function(){
  
  if ($('radioMedia'))
  {
    new MediaSelectBox('radioMedia', {width: 500, height: 465});
  }
  
  if ($('videoMedia'))
  {
    new VideoSelectBox('videoMedia', {width: 810, height: 615});
  }
  
  if ($('liveScoresMedia'))
  {
    new MediaSelectBox('liveScoresMedia', {width: 860, height: 465});
  }
});
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};
var LoginForm = Class.create({
  
  initialize: function()
  {
    this.form = $('members').down('form');
    this.form.observe('submit', this.submit.bindAsEventListener(this));
  },
  
  submit: function(e)
  {
    e.stop();
  
    new Ajax.Request(this.form.action, {
      parameters: this.form.serialize(),
      onComplete: this.complete.bind(this)
    });
  },
  
  complete: function(transport)
  {
    var result = transport.responseText.evalJSON();
    if (result.success)
    {
      // login succeeded, just reload the page
      window.location.reload();
    }
    else
    {
      this.add_message(result.message);
    }
  },
  
  add_message: function(message)
  {
    var breadcrumbs = $('breadCrumb');
    if (breadcrumbs)
    {
      breadcrumbs.hide();
    }
        
    var notice = $('notice');
    if (!notice)
    {    
      breadcrumbs.insert({before: "<span id='notice'><b>"+message+"</b></span>"});
    }
    else
    {
      notice.update("<b>"+message+"</b>");
      notice.setOpacity(0.5);
      notice.appear({duration: 1});      
    }
  }
  
});

document.observe('dom:loaded', function(){
  if ($('members'))
  {
    // new LoginForm();
  }
});
var InrunningComponent = Class.create({
  
  interval: 5,                               // seconds between polling
  url: "/vcbet/inrunning_refresh/index",     // where to call for the refresh
  params: {},
  
  initialize: function(element, options)
  {
    if (!element)
    {
      return;
    }    
    
    this.element  = element;
    this.scroller = new AutoScroller(this.element.down('.runningScroll'));
    this.content  = this.element.down('.scrollContent');
    
    if (options)
    {
      Object.extend(this, options);
    }
    
    this.set_timer();
  },
  
  set_timer: function()
  {
    setTimeout(this.check.bind(this), this.interval * 1000);
  },
  
  check: function()
  {
    new Ajax.Request(this.url, {
      method: 'get',
      onSuccess: this.content_received.bind(this),
      onFailure: this.failed.bind(this),
      parameters: this.params
    });
  },
  
  failed: function()
  {
    // keep calm and carry on
    this.set_timer();
  },
  
  content_received: function(transport)
  {
    var html = transport.responseText;
    
    this.content.update(html);
    this.scroller.recalculate();
    
    // all done, wait for the next update
    this.set_timer();
  }
  
});



var InrunningCouponRefresh = Class.create(CouponRefresh, {
  
  slider_changed: function(e)
  {
    var coupon = e.memo.element.up('.runningModule');
    if (!coupon)
    {
      return;
    }
    
    var id = coupon.id.gsub(/\D/, '');
    if (e.memo.state == 'opened')
    {
      this.open_coupons.push(id);
      this.remove_coupon_from_cache(id, this.closed_coupons);      
    }
    else
    {
      this.closed_coupons.push(id);
      this.remove_coupon_from_cache(id, this.open_coupons);
    }
  }
  
});


function openCashierWindow(url, options) {
  new CashierDialog(url, options);
}

// was called when the dialog closed, but can't use it without the proxy frame
// and that no longer works because the cashier has framebuster JS added now :o(
function cashierDialogClosed()
{
  document.fire("cashier:dialog:closed");
}

// The cashier goes off to another domain, and due to the same origin policy
// we can't spy on it. 
// Just refresh the balance every 30 seconds for 10 minutes for now.
var CashierDialog = Class.create({
  
  // default options for the popup window
  // pass in a hash to override them
	window_options: {
	  width:      787,
	  height:     755,
	  toolbar:    'no',
	  directories:'no',
	  status:     'no',
	  linemenubar:'no',
	  scrollbars: 'yes',
	  resizable:  'yes',
	  modal:      'yes',
	  top:        (window.screen.height - 755) / 2,
	  left:       (window.screen.width - 787) / 2
	},
  
  name: 'cashier_dialog',         
  proxy_path: "/cashier/dialog/", // path to the proxy/shim frame - not used for now because of framebuster JS in cashier
  delay: 10,                      // how long (seconds) before each refresh
  max:   600,                     // how long (seconds) to refresh for before we give up
  
  initialize: function(link, window_options)
  {
    this.link = link;
    Object.extend(this.window_options, window_options || {});
    
    document.observe("cashier:dialog:closed", this.closed.bind(this));
      
    this.open();
    this.wait();
  },
  
  open: function()
  {
    var opts = [];
    $H(this.window_options).each(function(x){
      opts.push(x.key+'='+x.value);
    });
    // this.window = window.open(this.proxy_path+'?url='+escape(this.link), this.name, opts.join(','));     
    this.window = window.open(this.link, this.name, opts.join(','));
    this.time_opened = 0;
  },
  
  closed: function()
  {
    clearTimeout(this.timer);
    this.update_balance();
  },
  
  wait: function()
  {
    // stop if we're over the max
    if (this.time_opened > this.max)
    {
      return;
    }
    
    this.timer = setTimeout(this.check_balance.bind(this), this.delay * 1000);
    this.time_opened += this.delay;
  },
  
  check_balance: function()
  {
    this.update_balance();
    this.wait();
  },
  
  update_balance: function()
  {
    // call global method to refresh the balance.
    // not nice, should really be firing an event, but hey.
    refresh_balance();
  }
    
});

// Balance refresh

var BalanceRefresh = Class.create({

  initialize: function()
  {
    this.url = "/"+VC_SITE+"/"+VC_LANG+"/balance/refresh/";
  },

  complete: function()
  {
    $("refreshLinkLogged2").show();
    $("refreshIconLoggedAnim").hide();
  },

  refresh: function()
  {
    if (!$("refreshLinkLogged2") || !$("refreshIconLoggedAnim"))
    {
      return;
    }

    $("refreshLinkLogged2").hide();
    $("refreshIconLoggedAnim").show();

    new Ajax.Request(this.url, {
      method: 'get',
      onComplete: this.complete.bind(this)
    });
  }  
});

// helper function to kick off the balance refresh
// called by clicking the balance refresh icon, and also by the CashierDialog
function refresh_balance()
{
  if (!BalanceRefresh.instance)
  {
    BalanceRefresh.instance = new BalanceRefresh();
  }
  BalanceRefresh.instance.refresh();
}

var screenLeft = (screen.width - width)/2;
var screenTop = (screen.height - height)/2;
var width = 770;
var height = 800;
var gameHeight = 50;  
var largeGameId;  
var miniGames = [];
var helpUrl;  

var startMiniGames = function() {
  $J.ajax({
  type: "GET",
  url: "/"+vcSite+"/"+vcLang+"/games/minigames_data",
  dataType: "xml",
  success: function(xml) {

    $J(xml).find('minigames').find('game').each(function(){
    var gameData = {
      gameName: $J(this).find('game_name').text(),
      gameClass: $J(this).find('game_class').text(),
      gameCss: $J(this).find('game_css_name').text()
    }
    miniGames[miniGames.length] = gameData;
    });
  
    $J(miniGames).each( function(index) {
      $J('#minigameContent').append('<div id="minigame' + (index + 1) + '" class="minigame"><a href="javascript:launchMiniGame(miniGames[' + index + ']);"><div id="mini' + miniGames[index].gameCss + '"><div class="miniplayMode ' + vcLang + 'PlayMode">' + playText + '</div></div></a></div>');
    });
    showMiniGames();
  },
  error: function () {
  	$J('#miniError').html(errorMsg + "<br><br><a href='javascript:miniGamesRetry();'>" + tryAgain + "</a>");
  }
  }); 
}   

var launchMiniGame = function(game) {
  setStrapText(game.gameName);
  hideMiniGames();
  getGameParams(game.gameClass, function(game){

    var flashvars = {preloaderXML: escape("/vcbet/"+vcLang+"/game/preloader?code="+game.game_id+"&minigame=false&skip=" + (vcLang == 'he' ? 'false' : 'true' ) + "&mode="+playMode)},
    params = {base: "/flash/games/"+game.orbis_game_name, allowScriptAccess: "sameDomain", "wmode": "opaque"},
    attributes = {};

    swfobject.embedSWF("/flash/games/Preloader/gameMini.swf", "minigame", "200", "200", "8", "", flashvars, params, attributes);
  });
}

var miniGamesRetry = function() {
	$J('#miniError').html("");
	startMiniGames();
}

var showMiniGames = function() {
  var startPos = 0;
  $J(miniGames).each( function(index) {
    $J('#minigame'+(index+1)).animate({top: startPos}, 1500);
    startPos += gameHeight;
  });
  $J('#minibanner').animate({top: 0}, 1500);
  $J('#minibuttons').animate({top: 40}, 1000);
  $J('#miniHelp').animate({top: -20}, 1000);
  $J('#miniFullScreen').animate({top: -20}, 1000);
  $J('#miniflashGame').animate({top: 210}, 1500);
  setStrapText(strapText);  
}

var hideMiniGames = function() {
  var startPos = 400;
  $J(miniGames).each( function(index) {
    $J('#minigame'+(index+1)).animate({top: startPos}, 1500);
    startPos -= gameHeight;
  }); 
  $J('#minibanner').animate({top: 50}, 1000);
  $J('#minibuttons').animate({top: 0}, 1500);
  $J('#miniHelp').animate({top: 6}, 1000);
  $J('#miniFullScreen').animate({top: 6}, 1000);
  $J('#miniflashGame').html("<div id='minigame'></div>");
  $J('#miniflashGame').animate({top: 0}, 1500);
}

var setStrapText = function(txt) {
	$J('#ministrap').html(txt);
}

function getGameParams(gameName, callback){
  var newGameName = camelCase("_"+gameName);
  helpUrl = '/'+vcSite+'/'+vcLang+'/pages/mini_games_help/'+(newGameName.substring(2, newGameName.length));

  $J.ajax({
    data: "name="+gameName,
    dataType: "json",
    url: "/vcbet/game/request_code",
    type: "GET",
    success: function(result) {
      //Properties of game
      var game = {
        game_id: result["game"]["game"]["id"],
        orbis_game_name: result["game"]["game"]["orbis_game_name"],
        larger_game_id: result["game"]["game"]["larger_game_id"]
      }
      largeGameId = game.larger_game_id;
      callback(game);
    },
    error: function () {
  	  $J('#miniError').html(errorMsg + "<br><br><a href='javascript:miniGamesRetry();'>" + tryAgain + "</a>");
    }
  }); 
}

function openFullSizeGame() {
  window.open("/vcgames/game/play?code="+largeGameId+"&mode="+playMode, 'game'+largeGameId, 'width='+width+',height='+height+',top='+screenTop+',left='+screenLeft+',toolbar=no,directories=no,status=no,linemenubar=no,scrollbars=no,resizable=yes,modal=yes');
}

function openAdvert(){
  window.open("/vcgames/" + vcLang + "/homepage", 'vcgames');
}

function openGameHelp() {
  window.open(helpUrl, 'game_help', 'width='+width+',height='+height+',top='+screenTop+',left='+screenLeft+',toolbar=no,directories=no,status=no,linemenubar=no,scrollbars=yes,resizable=yes,modal=yes');
}
   
// Called by game
function resizeGame() {
}

function camelCase(s) {
	s  = s.replace(/^\s+|\s+$/g,"");
	return (/\S[A-Z]/.test(s)) ?
		s.replace(/(.)([A-Z])/g, function(t,a,b) { return a + '_' + b.toLowerCase(); }) :
		s.replace(/( )([a-z])/g, function(t,a,b) { return b.toUpperCase(); });
}

function openGameLogin() {
	alert(loginText);
}
  var currentImage = 1; 
  var lastImage = 5;
  var spacing = 40;
  var slideSpeed = 1000;
  var offsetPos = [80, 60, 40, 20, 0];
  var images = [];
  var timeout;
  
  var startFeature = function() {
    $J.ajax({
      type: "GET",
      url: ("/" + VC_SITE + "/" + VC_LANG + "/generate_xml/features_area"),
      dataType: "xml",
      success: function(xml) {
        
        $J(xml).find('banners').find('banner').each(function(){
          
          var imageData = {
            image: $J(this).find('image').text(),
            linkURL: $J(this).find('link').text(),
            linkType: $J(this).find('link').attr("type"),
            linkWidth: $J(this).find('link').attr("width"),
            linkHeight: $J(this).find('link').attr("height"),
                description: $J(this).find('description').text()
            }
          images[images.length] = imageData;
        });
        if (images.length > 0) {
          $J(images).each(function(index){
            $J('#hpImages').append('<a href="' + featuresLink(images[index]) + '" onmouseover="clearTimer();" onmouseout="startTimer();"><img id="img' + (index + 1) + '" class="fadedOut" src="' + images[index].image + '" border="0" width="278" height="256"></a>');
            $J('#hpThumbnails').append('<p id="timg' + (index + 1) + '"><a href="javascript:bringToFront(' + (index + 1) + ');" title="'+images[index].description+'" onmouseover="clearTimer();" onmouseout="startTimer();"><img src="' + images[index].image + '" border="0" width="25" height="25"></a></p>');
          });
          if (images.length > 1) {
            slideOutImages();
          } 
          if (images.length > lastImage) {
            showNav();
          }
          $J('#img1').fadeIn(slideSpeed);
          $J('p#timg1 img').addClass('selected');
          if (images.length > 0) {
            startTimer();
          }
        }
      }
    });     
  }
  
  var rotateBanner = function() {
    var nextImage = currentImage+1;
    if (nextImage > images.length) { nextImage = 1};
    bringToFront(nextImage);    
  }
  
  var bringToFront = function(trg) {
    if (trg != currentImage) {
      clearTimer();
      if (images.length > lastImage) {
        if ($J('#hpScroller p')[lastImage].id == ("timg"+trg)) {
          $J('#hpRight').click();
        }
      }
      $J('#img' + currentImage).fadeOut(slideSpeed);
      $J('p#timg' + currentImage + ' img').removeClass('selected');
      $J('#img' + trg).fadeIn(slideSpeed);
      $J('p#timg' + trg + ' img').addClass('selected');
      currentImage = trg;
      startTimer();
    }
  }
  
  var clearTimer = function() {
    clearTimeout(timeout);
  }
  
  var startTimer = function() {
    timeout = setTimeout(rotateBanner, 5000);
  }
  
  var showNav = function() {
    $J('#hpLeft').animate({left: 0}, slideSpeed);
    $J('#hpRight').animate({left: '236px'}, slideSpeed);
    setUpLinks();
  }
  
  var slideOutImages = function() {
    var tmpOffset = 0;
    if (images.length < lastImage) {
      tmpOffset = offsetPos[images.length - 1];
    }
    $J('#hpScroller').animate({top: '218px'}, slideSpeed);  
    $J(images).each(function(index) {
      $J('#timg'+(index+1)).animate({left: (tmpOffset + (spacing * index))}, slideSpeed);
    });
  }
  
  var setUpLinks = function() {
    
    var $leftButton = $J('#hpLeft');
    var $rightButton = $J('#hpRight');
    var $images = $J('#hpThumbnails p');
    
    $leftButton.unbind('click');
    $rightButton.unbind('click');
    
    $rightButton.click(function(event) {
 
      $images.eq(0).animate({'left': -spacing}, 1000, function() {
 
        $J(this).appendTo('#hpThumbnails');
        setUpLinks();
      });
 
      $images.eq(1).animate({'left': 0}, slideSpeed);
      $images.eq(2).animate({'left': spacing}, slideSpeed);
      $images.eq(3).animate({'left': spacing * 2}, slideSpeed);
      $images.eq(4).animate({'left': spacing * 3}, slideSpeed);
      $images.eq(5).css('left', spacing * 5).animate({'left': spacing * 4}, slideSpeed);
    });
    $leftButton.click(function(event) {
 
      $images.eq(0).animate({'left': spacing}, slideSpeed);
      $images.eq(1).animate({'left': spacing * 2}, slideSpeed);
      $images.eq(2).animate({'left': spacing * 3}, slideSpeed);
      $images.eq(3).animate({'left': spacing * 4}, slideSpeed);
      $images.eq(4).animate({'left': spacing * 5}, slideSpeed);
      $images.eq(5).css('left', -spacing).animate({'left': 0}, slideSpeed, function() {
 
        $J(this).prependTo('#hpThumbnails');
        setUpLinks();
      });
    });
  }
  
  var featuresLink = function(img) {
    if (img.linkType == "internal") {
      return img.linkURL;
    } else {
      if (!isNaN(parseInt(img.linkWidth))) {
        return "javascript:featuresAreaPopUp('" + img.linkURL + "'," + img.linkWidth + "," + img.linkHeight+ ");";
      }
      return "javascript:featuresAreaPopUp('" + img.linkURL + "',0,0);";
    }
  }
// inRunning Javascript API

jQuery.inRunning = {
  website : VC_SITE,
  language : VC_LANG,
  price_format : VC_USER_PRICE_FORMAT,
  currency_code : VC_USER_CURRENCY_SYMBOL,
  inrunning_results_url : INRUNNING_RESULTS_URL,
  inrunning_goto_event_url : INRUNNING_GOTO_EVENT_URL,
  inrunning_goto_live_event_url : INRUNNING_GOTO_LIVE_EVENT_URL,
  inrunning_external_url : INRUNNING_EXTERNAL_URL,
  inrunning_level3_url : INRUNNING_LEVEL3_URL,
  inrunning_diary_url : INRUNNING_DIARY_URL,
  inrunning_remote_url: INRUNNING_REMOTE_URL,

  // Use this to interact with the flash app
  get_movie_name: function(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
      return window[movieName]
    }
    else {
      return document[movieName]
    }
  },
  
  // Resize the inrunning div.
  resize : function(fheight) {
    $J('#navigation').css('height', fheight);
		$J('object#bip').attr({height: fheight});
  },

  // To remove all bets pass an empty array etc
  // To add a bet pass the full array with the new bet included
  // etc.
  update_bets: function(arr) {
    var flash_app = this.get_movie_name('bip');
    if (flash_app)
    {
      flash_app.update_bets(arr);
    }
  },
  
  // Navigate to the coupon page of an event
  goto_event: function(event_id) {
    window.location = this.inrunning_goto_event_url + "/" + event_id;
  },
  
  // Navigate to the event in the live app
  goto_live_event: function(event_id) {
    var queryStringStartIndex = this.inrunning_goto_live_event_url.indexOf('?');
    var urlPart = this.inrunning_goto_live_event_url.substring(0, queryStringStartIndex)
    var queryStringPart = this.inrunning_goto_live_event_url.substring(queryStringStartIndex)
    window.location = urlPart + "/" + event_id + queryStringPart;
  },
  
  // Navigate to the inrunning diary
  goto_diary: function() {
    this.goto_live_event('DIARY');
  },
  
  // Navigate to the results page of a sport
  get_results: function(sport_id) {
    var maps = {"100" : "", "400" : "golf", "200" : "racing", "600" : "tennis", "366" : "greyhounds"}
    var sport = maps[sport_id] || "";
    MM_openBrWindow(this.inrunning_results_url + sport, "", "width=860,height=465,scrollbars=yes");
  },
  
  // Display an external feed for an event
  display_external_feed: function(event_id) {
    MM_openBrWindow(this.inrunning_external_url + "/" + event_id, "", "width=860,height=465,scrollbars=yes")
  },
  
  // Display a level3 feed for an event
  display_level3_feed: function(event_id) {
    MM_openBrWindow(this.inrunning_level3_url + "/" + event_id, "", "width=810,height=615,status=no,toolbar=no,location=no,menubar=no,resizable=no")
  },
    
  // Place a Bet
  // Example:
  // jQuery.inRunning.place_bet("2649960200", "3.000", "1353932302", "3", "1", "DR Congo", "DR Congo v Libya")
  place_a_bet : function(outcome_id, price_description, price_id, price_decimal, place_terms_deduction, outcome_description, event_description, each_way, starting_price, market_description) {
    add_to_slip(outcome_id, 
                price_description,
                price_id,
                price_decimal,
                this.price_format,
                this.currency_code,
                true,
                place_terms_deduction,
                outcome_description,
                event_description,
                each_way,
                starting_price,
				market_description);
  },

  // Remove a Bet.
  // Example:
  // jQuery.inRunning.remove_a_bet('2283248200', '1175852102');
  remove_a_bet : function(outcome_id, price_id) {
    remove_from_slip(this.website, this.language, outcome_id, price_id);
  },

  // Remove all bets from betslip.
  remove_all_bets : function(){
    remove_all(this.website, this.language);
  },

  // Scroll page to top.
  scroll_to_top : function() {
    scroll(0,0);
  },

  //Get the size of the inrunning div.
  get_size : function() {
    return jQuery('#inrunning').innerHeight();
  },

  //This accepts price update notifications from the flash appGet the size of the inrunning div.
  notify_price_update : function(outcome_id, price_description, price_id, price_decimal) {
    ; // Just a stub for now
  }


}

function getMovie(movieName) {
  return window[movieName] || document[movieName];
}

try {
		var flashHeight = getMovie('bip').getSWFHeight();
		$J('#navigation').css('height', flashHeight);
		$J('object#bip').attr({height: flashHeight});
	}
catch(err) {
		$J('#navigation').css('height', 100);
		$J('object#bip').attr({height: 100});
	}


