(function($){

// ################ cartIcon ################
var cartIcon = {
	f_init: false,
	iframe: null,
	f_shown: false,
	cnt: 0,
	opt: {
		parens: '',
		autoHideNum: false,
		trayAnchor: null
	},
	
	init: function (opt) 
	{
		if (cartIcon.f_init) return;

		if (opt) { 
			$.extend(cartIcon.opt, opt);
		}

		$().ready(function() {
			// cross-domain iframe hack
			if (!$().PS.app('pvGet', 'isPsHost')) {
				cartIcon.iframe = $("<iframe></iframe>").hide().appendTo("body");
			}

			if (cartIcon.opt.f_tray)
				cartIcon.initTray();
			cartIcon.refresh();
		});

		cartIcon.f_init = true;
	},
	
	initTray: function () 
	{
		if (!$(".psCartIcon").length || !cartIcon.opt.trayAnchor) return;

		var tray = $("<iframe id='psCartTray' scrolling='no'></iframe>")
				.css({"left":"-10000px","overflow":"hidden"})
				.appendTo("body");
		var pos = cartIcon._trayOfs();
		var trafOfs = {left: pos.o, top: pos.t};		
		tray.width(pos.w);
		tray.css("top", trafOfs.top);
		cartIcon.trayFrame = tray;
		$(".psCartIcon").live('mouseover', function () {
			if (!cartIcon.cnt) return; //bail if cart's empty
			$(this).data('cartIconHover', true);
			setTimeout(function() { //add a 1 second hover delay to see the cart tray
				if ($(".psCartIcon").data('cartIconHover')) {
					var pos = cartIcon._trayOfs();
					if (!cartIcon.f_shown) {
							$("#psCartTray").hide();
							cartIcon.f_shown = true;
					}
					if ($.browser.msie)
						$("#psCartTray").css('border','2px solid #ddd');
					$("#psCartTray").css("left", pos.o);
					$("#psCartTray").slideDown();		
				}
			}, 1000);
		});
		$(".psCartIcon").live('mouseout', function () {
			$(this).data('cartIconHover', false);
		});
		$("#psCartTray").live('mouseleave', function () {
			$("#psCartTray").slideUp(400, function () { $("#psCartTray").css("left", "-10000px")});						
		});
	},

	_trayOfs: function ()
	{
		var sel = cartIcon.opt.trayAnchor;
		var w, o;
		var psciOfs = $(".psCartIcon").offset();
		if ($(sel).length) {
			w = $(sel).width();
			o = $(sel).offset().left;
		} else {
			w = 500; 
			o = psciOfs.left - Math.round(w/2);
		}

		var t = psciOfs.top + $(".psCartIcon").outerHeight();

		return {'w': w, 'o': o, 't': t};
	},
	
	_update: function (n)
	{
		// just in case...
		if (!n) n = 0;

		cartIcon.cnt = n;

		$('.psCartIconNum').each(function() {
			switch (cartIcon.opt.parens) {
			case 'parens':
				this.innerHTML = '(' + n + ')';
				break;
			case 'bracket': 
				this.innerHTML = '[' + n + ']';
				break;
			default:
				this.innerHTML = n;
			}
			
			if (cartIcon.opt.autoHideNum) {
				n ? $(this).show() : $(this).hide();
			}
		});
		
		$('.psCartIcon').each(function() {
			if (n) $(this).addClass('filled');
			else $(this).removeClass('filled');
		});
		
		$('.psCartIconCheckout').each(function() {
			$(this).toggle(n > 0);
		});
	},
	
	refresh: function ()
	{
		var host = '';
		if (location.protocol != 'https:') 
			host = $().PS.app('pvGet', 'custom_url_ps');

		if (cartIcon.iframe) {
			// use cross-domain iframe hack
			cartIcon.iframe.attr('src', host +
				'/cart/cartIconIframe?host=' + location.host);
		}
		else {
			$.ajax({
				url: '/ajax/cartAct',
				type: 'POST',
				dataType: 'json',
				global: true,
				data: {
					_ACT: 'cartItemQtySeller'
				},
				bsapiCB: function (d) {
					cartIcon._update(d.n_item);
				}
			});
		}

		//refresh tray
		if ($("#psCartTray").length)
			$("#psCartTray").get(0).src = host + '/cart/tray?' + (new Date()).getTime();

	}
};

$.fn.PS.cartIcon = function(method) {
	if (cartIcon[method]) {
		return cartIcon[method].apply(this, Array.prototype.slice.call(arguments, 1));
	}
	else if (typeof method === 'object' || !method) {
		return cartIcon.init.apply(this, arguments);
	}
	else {
		$.error('PS.cartIcon: undefined method [' + method + ']');
	}
};

// ################ cartAdd ################
var cartAdd = {
	TABS:		{
		PR: 'Prints', 
		PRD: 'Products', 
		BND: 'Packages', 
		DL: 'Downloads'
	},

	_data: {
		items: {},
		tabD: {
			'Prints': {cnt: 0, sub: 0.00},
			'Products' : {cnt: 0, sub: 0.00 },
			'Packages' : {cnt: 0, sub: 0.00 },
			'Downloads' : {cnt: 0, sub: 0.00 }
		},
		cartD: {cnt: 0, sub: 0.00}
	},

	curBnd: null,
	bndData: null,
	initD: null,

	win:		null,
	bndWin:		null,
	winState: 	0,

	init: function (options) {},

	_cartSzProp : {paneIniHt : null, paneIniProp : null},

	_objZero: function (obj)
	{
		$.each(obj, function(k,v) {
			if (typeof(v) == 'object')
				cartAdd._objZero(v);
			else obj[k] = 0;
		});
	},

	_dataReset : function(f_keep_items) 
	{
		$.each(cartAdd._data, function(k,v) {
			switch (k) {
			case 'items':
				if (f_keep_items) break;

				delete cartAdd._data[k];
				cartAdd._data[k] = {};
				break;
			default:
				cartAdd._objZero(v);
			}
		});
	},
	
	_dataUpd : function(items)
	{
		//update item data
		$.extend(true, cartAdd._data.items, items);

		//clear display total data
		cartAdd._dataReset(true);
		
		//cleanup and update totals
		$.each(cartAdd._data.items, function(k, v) { 
			var p = 0.00;

			//delete objects that no longer have quantity
			if (v.QTY == 0 || v.QTY == '') {
				delete cartAdd._data.items[k];
			} else {
				//update type specific counts
				switch (v.TYPE) {
				case 'PR':
				case 'PRD':
				case 'BND':
					t = cartAdd.TABS[v.TYPE];
					break;
				case 'PU':
				case 'RF':
				case 'RM':
					t = 'Downloads';
					break;
				}

				cartAdd._data.tabD[t].cnt += v.QTY;
				p = parseFloat(v.PRICE) * v.QTY; 
				
				// bundles are always single price
				if (v.TYPE != 'BND' && v.TYPE != 'RM') p *= v.IMAGES.length;

				cartAdd._data.tabD[t].sub += parseFloat(p.toFixed(2));
				cartAdd._data.cartD.cnt += v.QTY;
				cartAdd._data.cartD.sub += p;
			}
		});

		$.event.trigger('update_display_totals');
	},

	_trDataUpd: function (tr)
	{
		var d = $(tr).data('cartAdd');
		var qty = parseInt($(tr).find("input[name^='QTY']").val());
		var opt = $(tr).find("SELECT[name^='OPT'],INPUT[name^='OPT']").first().val();
		var tot, r = {};

		if (isNaN(qty)) qty = 0;

		switch (d.TYPE) {
		case 'BND':
			r[d.FUP_ID] = {
				FUP_ID: d.FUP_ID,
				TYPE: d.TYPE,
				PRICE: d.PRICE,
				QTY: qty
			};
			break;
		default:
			r[d.FUP_ID] = {
				FUP_ID: d.FUP_ID,
				TYPE: d.TYPE,
				PRICE: d.PRICE,
				IMAGES: d.IMAGES,
				QTY: qty,
				OPT: (opt ? opt : '')
			};
		}

		cartAdd._dataUpd(r);		

		// update lineItemTotal
		tot = d.PRICE * qty * d.IMAGES.length;
		if (isNaN(tot)) tot = '0.00';
		else tot = tot.toFixed(2);
		$(tr).find("SPAN.lineItemTotal").html(tot);
	},

	_trQtyHandler: function (tr)
	{
		/* Highlight the row if selected */
		if (tr.find(':input[name*="QTY"]').first().val() > 0) {
			tr.addClass("psCartAddTrHasQty");
			tr.nextUntil("TR.psCartLineItem").children().addClass("psCartAddTrHasQty");
		} else {
			tr.removeClass("psCartAddTrHasQty");
			tr.nextUntil("TR.psCartLineItem").children().removeClass("psCartAddTrHasQty");
		}

		cartAdd._trDataUpd(tr);
	},

	_trRadioHandler: function (tr, setVal)
	{
		var radio = $(tr).find('input:radio').first();
		var f_setVal = (typeof setVal) != 'undefined';
		
		if (f_setVal) 
			radio.prop('checked', setVal);			


		$(tr).toggleClass("psCpSelected", radio.prop('checked'));

		// set QTY hidden
		$(tr).find("input[name^='QTY']").val(radio.prop('checked') ? '1' : '0');
		
		if (!f_setVal && (radio.attr('name') == 'BND') && radio.prop('checked')) {
			//check for a single image selected from batch select
			var i_id =  cartAdd.initD.I_ID;
			var batch_sel_cnt = 0;
			if (typeof i_id == 'object') {
				$.each(i_id, function(k,v) { tmp_id = v; batch_sel_cnt++; });
				if (batch_sel_cnt == 1) i_id = tmp_id;
			}

			//bypass cart selection for single images that have no finish options
			if (typeof i_id == 'string') {
				d = $(tr).data('cartAdd');
				var p = {_ACT: 'cartBndSkipSelection', I_ID : i_id, FUP_ID: d.FUP_ID, PRF_ID: d.PPUP_PRICE_ID};
				$.ajax({
					url: '/ajax/cartAct', 
					type: 'GET', 
					dataType: 'json',
					data: p,
					global: true,
					bsapiCB: function(data) {
						delete data._ACT;
						cartAdd.bndData = [];
						var i = 0;
						$.each(data, function(k,sel) {
							cartAdd.bndData.push(sel);
							i++;
						});
						if (i) { //all items added since no selection is required
							$('#psCpPackages TR.item').each(function() {
								cartAdd._trDataUpd(this);
							});
						} else { //open the selection window
							cartAdd._bndDialogOpen($(tr).data('cartAdd'));
						}
					}
				});
			} else {
				cartAdd._bndDialogOpen($(tr).data('cartAdd'));
			}
		} else {
			cartAdd._trDataUpd(tr);
		}
	},
	
	_qtyClick: function(qtyObj, d)
	{
		var n = parseInt(qtyObj.val());

		if (n == 99) return;

		if (n > 0) qtyObj.val(n + d)
		else if (d == 1) qtyObj.val(1);

		cartAdd._trQtyHandler($(qtyObj).closest('TR'));
	},
	
	_dialogDestroy: function ()
	{
		cartAdd.win.dialog("destroy");
		cartAdd.win.remove();
		if (cartAdd.fq) {
			cartAdd.fq._delete();
			cartAdd.fq = null;
		}
		delete cartAdd.win;
	},

	_nukeWin : function() {
		// FIXME: need to look into memory cleanup?
		$("#psCartAddPaneMain").tabs("destroy");

		cartAdd._dialogDestroy();
		cartAdd._bndDialogDestroy();

		$(window).unbind('resize');

		cartAdd._dataReset();
		cartAdd.winState = 0;
	},

	_createWin: function (d)
	{
		// reusables
		var		t, str;

		cartAdd.initD = $.extend({},d);
		if (cartAdd.win) return;
		
		//set up the content divs
		cartAdd.win = $('<div id="cartWin"><div class="psWaitingMd"><img src="/img/icon/ajax-loader-medium.gif" border="0">&nbsp&nbsp;Please wait.</div></div>');
		$(".psWaitingMd").bind("bsapi_error", function() {
			$(this).html('We are unable to process your request at this time.');
		});

		// dialog must be opened to avoid shitty latency.
		cartAdd.win.dialog({
			position:'center', 
			resizable:false,
			resize: 'auto',
			autoOpen:true, 	// bleh, lame.
			modal:true,
			stack: false, 
			width: 450,
			height: 'auto',					
			title:'Add to Cart',
			dialogClass: 'ps'
		});

		//load the frame content
		cartAdd.win.load('/ajax/panes/cartAdd', cartAdd.initD, function() {
			var sc = cartAdd.win;

			cartAdd.win.dialog('open');

			//tab setup
			var sel = null, selSub = null, tab;

			if (d.TAB) {
				switch (d.TAB.toUpperCase()) {
				case 'PR':
				case 'PRD':
				case 'BND':
				case 'DL':
					tab = cartAdd.TABS[d.TAB];
					break;
				case 'PRINTS':
					tab = 'Prints'; break;
				case 'PRODUCTS':
					tab = 'Products'; break;
				case 'PACKAGES':
					tab = 'Packages'; break;
				case 'DOWNLOADS':
					tab = 'Downloads'; break;
				case 'RM':
				case 'RF':
				case 'ROYALTY-FREE':
				case 'RIGHTS-MANAGED':
				case 'COMMERCIAL-USE':
					tab = 'Downloads';
					selSub = 'Commercial';
					break;
				case 'PU':
				case 'PERSONAL-USE':
					tab = 'Downloads';
					selSub = 'Personal';
					break;
				}

				var i = 0;
				$("UL#psCpTabs LI A").each(function() {
					if ($(this).html() == tab) {
						sel = i;
					}
					i++;
				});
			}

			// default tab
			if (sel === null)
				sel = $("#psCpTabs LI").length-1;

			$("#psCartAddPaneMain").tabs({
				selected: sel, 
				select: function () { cartAdd._resizeTO(); }
			});
			$("#psCartAddPaneMain ul").removeClass('ui-widget-header');

			//update title counts from data
			$("#ui-dialog-title-cartWin").append('&nbsp;(<span id="cartCountTitle">'
				+ cartAdd._data.cartD.cnt + '</span>)');

			cartAdd._resize();
			cartAdd.winState=1;

			//resize event
			$(window).resize(cartAdd._resize);

			//fotoquote obj instantiate
			if ($('#psCpDownloads DIV.psCpDownloadsRm').length) {
				if (!cartAdd.fq) {
					cartAdd.fqCE = _bsMm.ceNew('fq', cartAdd);
					cartAdd.fqCE.addCB(cartAdd._fqCB);
					var fqDom = $("#psCpDownloads DIV.psCpDownloadsRm .fq").get(0);
					cartAdd.fq = _bsMm.oNew(BS.com.FotoQuotePrice, fqDom, cartAdd.fqCE, false, '/ajax/fotoQuoteAct');
				}
				cartAdd.fq.reset();
				cartAdd.fq.init({I_ID: $("#psCpDownloads  .psCpDownloadsRm").data("rmImage")});
			}

			/* ******** UI controls binding ******** */

			// close/destroy/submit
			cartAdd.win.bind("dialogclose", cartAdd._nukeWin);
			$("#cartAddClose").click(cartAdd._nukeWin);
			$("#cartAddSubmit").bind('update_display_totals', function() {
				if (cartAdd._data.cartD.cnt) {
					$(this).removeClass('disabled');
					$(this).unbind('click');
					$(this).click(cartAdd._submit);
				} else {
					if (!$(this).hasClass('disabled'))
						$(this).addClass('disabled');
					$(this).unbind('click');
				}
			});

			// QTY input
			$("INPUT:text[name^='QTY']", sc).focus(function(e) {
				if ($(this).val() == 0)
					$(this).val('');
			})
				.blur(function(e) {
					if ($(this).val() == '')
						$(this).val(0);
					
			})
				.keypress(function(e){
					var k = e.which;
					if ((k<48 && k!=0 && k!=8 && k!=46) || k > 57)
						e.preventDefault(); 
			})
				.keyup(function(e) {
					cartAdd._trQtyHandler($(this).closest('TR'));
			});

			// QTY buttons
			$(".psCpQtyUp", sc).click(function() {
				cartAdd._qtyClick($(this).closest("TR").find(':input[name*="QTY"]').first(),1);
			})
				.hover(function() {$(this).css('cursor','pointer');}, function() {$(this).css('cursor','auto');});
			$(".psCpQtyDown", sc).click(function() {
				cartAdd._qtyClick($(this).closest("TR").find(':input[name*="QTY"]').first(),-1);
			})
				.hover(function() {$(this).css('cursor','pointer');}, function() {$(this).css('cursor','auto');});

			// FINISH select
			$("SELECT[name^='OPT']", sc).change(function(e){
				if ($(this).closest("TR").find(':input[name*="QTY"]').first().val() == 0) 
					cartAdd._qtyClick($(this).closest("TR").find(':input[name*="QTY"]').first(), 1);
				cartAdd._trDataUpd($(this).closest('TR'));
			});

			// package/PU/RF radio handling
			$("TABLE.psCpRadioSelect", sc).each(function() {
				$(this).bind('click', function(e) {
					var t = $(e.target);
					var dataA = [];
					var targetTR = t.closest('TR.item');
					if (!targetTR.length) return;
					var radio = targetTR.find('input:radio').first();
					
					//select/edit button handling
					if (t.hasClass("psCpRadioDeselBtn")) 
						return cartAdd._trRadioHandler(targetTR, false);
					else if ((t.prop('tagName').toLowerCase() != 'input') &&
							 !t.hasClass("psCpRadioEditBtn")) 
						return e.stopPropagation();

					// TR click selection
					if (!t.is(radio) && !radio.prop('checked'))
						radio.prop('checked', true);
					
					$(this).find('TR.item').each(function() {
						cartAdd._trRadioHandler(this);
					});

					e.stopPropagation();
				});
			});

			// download license type
			var dlcsc = $('#psCpDownloads DIV.psCpDownloadsChooser');
			if (dlcsc.length) {
				$("#psCpDownloads .psCpDownloadsPu").hide();
				$("#psCpDownloads .psCpDownloadsRmRf").hide();

				$('.puBtn', dlcsc).click(function (e) {
					$("#psCpDownloads .psCpDownloadsPu").show();
					dlcsc.hide();
					cartAdd._resize();
				});
				$('.rmBtn', dlcsc).click(function (e) {
					$("#psCpDownloads .psCpDownloadsRmRf").show();
					dlcsc.hide();
					cartAdd._resize();
				});
				$('#psCpDownloads A.psCpShowChooser').click(function (e) {
					// reset radios
					$('.psCpDownloadsRf TR.item').each(function() {
						cartAdd._trRadioHandler(this, false);
					});
					$('.psCpDownloadsPu TR.item').each(function() {
						cartAdd._trRadioHandler(this, false);
					});

					dlcsc.show();
					$("#psCpDownloads .psCpDownloadsRmRf").hide();
					$("#psCpDownloads .psCpDownloadsPu").hide();

					if (cartAdd.fq) cartAdd.fq.reset();

					$("#psCpDownloads input:checked").prop("checked", false);
					cartAdd._resize();
				});

				switch (selSub) {
				case 'Personal':
					$('.puBtn', dlcsc).click();
					break;
				case 'Commercial':
					$('.rmBtn', dlcsc).click();
					break;
				}
			}

			/* ******** update_display_totals handlers ******** */

			// tabs subtotals
			$.each(cartAdd.TABS, function(k,v) {
				$('#psCp' + v + 'Sub').bind("update_display_totals", function() {
					t = cartAdd._data.tabD[v].sub;
					$(this).html(t.toFixed(2));
				});
			});

			//cart count/subtotal
			$("#cartCountTitle").bind("update_display_totals", function() {
				$(this).html(cartAdd._data.cartD.cnt);
			});
			$("#psCpCartSub").bind("update_display_totals", function() {
				$(this).html(cartAdd._data.cartD.sub.toFixed(2));
			});

			//tab counts
			$.each(cartAdd.TABS, function(k,v) {
				$('#psCp' + v + 'Tab A').bind("update_display_totals", function() {
					var cnt = cartAdd._data.tabD[v].cnt;
					var html = cnt ? ('<span>(<span>' + cnt + '</span>)</span>') : '';
					$(this).html(v + html);
				});
			});

			/* ******** end handlers ******** */

			cartAdd.setWin('open');

			//set ini vals for resizing
			cartAdd._cartSzProp['paneIniHt'] = parseInt($("DIV .cartAddTbBody").height());
			cartAdd._cartSzProp['paneIniProp'] = cartAdd._cartSzProp['paneIniHt'] / $(window).height();
			cartAdd._resizeTO();
		});
	},

	_getDragOpts: function () 
	{
		return {
			opacity: 0.7, 
			helper: "clone", 
			appendTo: "#psCpPackageImgSel",
			revert: "invalid",
			containment: '#psCpPackageImgSelWin'
		};
	},

	_bndDelThmbClick: function () { cartAdd._bndDelThmb($(this).closest("LI")); },

	_bndDelThmb: function (slot)
	{
		var matte = $(slot).children(".thmbMatte");
		var frame = matte.children(".thmbFrame");
		matte.children(".thmb_del").hide();	
		frame.hide();
		matte.children("img").remove();
		matte.children(".dragNote").show();
		$(slot).removeClass("imgDropped");
	},

	//adds thumb to drop slot, displays crop preview if pr/prd
	_bndAddThmb: function (img, slot) 
	{
		var matte = $(slot).children(".thmbMatte");
		$(slot).addClass("imgDropped");
		//.css('backgroundImage', 'url('+ui.helper[0].src+')');
		var frame = matte.children(".thmbFrame");
		matte.children("img").remove();

		var clone = img.clone();

		if (cartAdd.curBnd.F_MULTI) {
			var dopts = cartAdd._getDragOpts();
			dopts.helper = function ( ev ) { return $('img', this).clone(); }
			matte.draggable(dopts);
			matte.children(".thmb_del").show();
		}

		var msz = matte.width();
		var fdim = {width: msz, height: msz};
		var pd = $(slot).closest(".productSlots").data('fup');
		var imd = clone.data('image');
		var il, is, iw = parseInt(imd['I_WIDTH']),  ih = parseInt(imd['I_HEIGHT']);
		var longd, shortd;
		if (iw > ih) longd = 'width', shortd = 'height', il = iw, is = ih;
		else longd = 'height', shortd = 'width', il = ih, is = iw;

		var thdim = {};
		thdim[shortd] = Math.round(msz * (is/il));
		thdim[longd] = msz;
		var f_crop = (cartAdd.curBnd.F_CROP == 't'); 

		if (pd['FUP_WIDTH']) { //calc crop preview if physical product			
			var cl = parseInt(pd['FUP_WIDTH']), cs = parseInt(pd['FUP_HEIGHT']);
			if (cl < cs) { var t = cl; cl = cs; cs = t; }

			
			if (f_crop) {
				fdim[shortd] = msz * Math.min(cs/cl, is/il);
				fdim[longd] = fdim[shortd] * (cl/cs);
			} else {
				fdim[shortd] = msz * cs/cl;
				var shsz = msz * Math.min(cs/cl, is/il);
				thdim[shortd] = Math.round(shsz);
				thdim[longd] = Math.round(shsz * (il/is));

				/*
				if ("FUP009uPrq17XtLw" == pd['FUP_ID'])
					console.log(f_crop, msz, cs/cl, is/il, shsz, fdim, thdim);
				*/
			}
			frame.show();
		} else {
			frame.hide();
		}

		var crop_border_w = 1 * 2;
		frame.width(fdim.width - crop_border_w + "px");
		frame.height(fdim.height - crop_border_w +"px");

		//HAX!if image not loaded yet correct for rounding error
		if (f_crop && clone.width() == 0) clone.one('load', cartAdd._bndThmbLoad);
		if (!f_crop || clone.width() == 0) {
			clone[shortd](thdim[shortd] + 'px');
			clone[longd](thdim[longd] + 'px');
		}

		matte.children(".dragNote").hide();
		frame.position({my:'center center', at: 'center center', of: matte});
		matte.append(clone);
		clone.position({my:'center center', at: 'center center', of: matte});	

	},

	//rounding error hack to descale thumb when loaded
	_bndThmbLoad: function () 
	{ 
		var t = $(this);
		if (Math.max(t.width(), t.height()) == t.parent().width()) {
				t.width('auto'); 
				t.height('auto');
		}
	},

	_bndDrop: function (e, ui) 
	{
		cartAdd._bndAddThmb(ui.draggable.parent().find("img"), this);
	},
	
	_bndDialogDestroy: function ()
	{
		if (cartAdd.bndWin) {
			cartAdd.bndWin.dialog("destroy");
			cartAdd.bndWin.remove();
			delete cartAdd.bndWin;
		}
	},

	_bndDialogOpen: function (d)
	{
		var html = '<div id="psCpPackageImgSelWin"><div class="psWaitingMd"><img src="/img/icon/ajax-loader-medium.gif" border="0">&nbsp&nbsp;Please wait.</div></div>';
		var opts = {
			position:'center', 
			resizable:false,
			resize: 'auto',
			autoOpen:true, 	// bleh, lame.
			modal:true,
			stack: false, 
			width: 450,
			height: 'auto',
			title:'Select Package Images',
			dialogClass: 'ps psCpPackageSelWin sDark',
			close: cartAdd._bndDialogClose
		};
		
		if (!cartAdd.bndWin) {
			cartAdd.bndWin = $(html);

			// dialog must be opened to avoid shitty latency.
			cartAdd.bndWin.dialog(opts);

			cartAdd.bndWin.bind("dialogclose", cartAdd._bndDialogClose);
		}
		else if (cartAdd.bndWin.data('fupId') == d.FUP_ID) {
			// same bundle as before - no need to reload
			cartAdd.bndWin.dialog('open');
			cartAdd._bndResize();
			return;
		}
		else {
			// reset the dialog
			cartAdd._bndDialogDestroy();
			cartAdd.bndWin = $(html);
			cartAdd.bndWin.dialog(opts)
		}

		delete cartAdd.bndData;
		cartAdd.curBnd = d;

		cartAdd.bndWin.data('fupId', d.FUP_ID);

		var p = {FUP_ID: d.FUP_ID, PRF_ID: d.PPUP_PRICE_ID};

		if (cartAdd.initD.G_ID)
			p.G_ID = cartAdd.initD.G_ID;
		else
			p.I_ID = cartAdd.initD.I_ID;

		cartAdd.bndWin.load('/ajax/panes/cartAdd-bundle', p, cartAdd._bndWire);
	},
	
	_bndDialogClose: function ()
	{
		if (!cartAdd.bndData) {
			$('#psCpPackages TR.item').each(function() {
				cartAdd._trRadioHandler(this, false);
			});
		}
	},

	_bndDialogSubmit: function ()
	{
		var sc = cartAdd.bndWin;
		var fup, finish;
		
		cartAdd.bndData = [];

		// check if bundle is filled
		if ($('#psCpPackageImgSel', sc).find(".dragNote:visible").length) {
			return alert('Please select images for all the products in this package.');
		}
		
		$('DIV.productSlots', sc).each(function () {
			fup = $(this).data("fup").FUP_ID;
			finish = $(this).prev().find('select[name^=OPT],input[name^=OPT]').first();
			$("IMG", this).each( function () { 
				cartAdd.bndData.push({
					FUP_ID: fup, 
					I_ID: $(this).data("image").I_ID,
					FINISH: (finish.length ? finish.val() : '')
				});
			});
		});

		$('#psCpPackages TR.item').each(function() {
			cartAdd._trDataUpd(this);
		});
		
		cartAdd.bndWin.dialog('close');
	},

	_bndResize: function ()
	{
		var minH = $("#psCpPackageImgSel h2").height() + $("#psCpPackageImgSel .prodToolBar").height() + $("#psCpPackageImgSel .productSlots LI").height();
		var pc = $('#psCpPackageImgSel .package_contents');

		$().PS.dialogResize(cartAdd.bndWin, minH, pc);

		cartAdd.bndWin.dialog("option", "width", "90%");
		cartAdd.bndWin.dialog("option", "position", "center");
	},

	_bndWire: function () 
	{
		var sc = cartAdd.bndWin;

		cartAdd.bndWin.dialog('open');
		
		// footer buttons
		$('#packageImgSelCancel', sc).bind('click', function() {
			cartAdd.bndWin.dialog('close');
		});
		$('#packageImgSelSubmit', sc).bind('click', cartAdd._bndDialogSubmit);
		if (cartAdd.curBnd.F_MULTI)
			$('DIV.filmstrip IMG', sc).draggable(cartAdd._getDragOpts());
		else
			$('DIV.filmstrip').hide();

		$('#psCpPackageImgSel .dragTarget', sc).droppable({
			hoverClass: "dragTarget-hover",
			drop: cartAdd._bndDrop
		});

		$('.cartAddClearAll',sc).bind('click', cartAdd._bndItemClearAll);

		//filmstrip
		$('.psFsPrev', sc).css('visibility', 'hidden');

		//hide next button if uneeded
		if ($('.psFsViewPort',sc).width() >= $('.psFsViewPort UL',sc).width())
			$('.psFsNext',sc).css('visibility', 'hidden');

		$('.psFsNext, .psFsPrev', sc).bind('click', cartAdd._fsClick);

		if (cartAdd.curBnd.F_MULTI)
			$('.thmb_del',sc).bind('click', cartAdd._bndDelThmbClick );

		var i_id = $('#psCpPackages .psCpSelected').data('cartAdd').IMAGES;
		if (!$.isArray(i_id)) i_id = [i_id];

		if (i_id.length == 1) {
			var s = '';
			if (cartAdd.curBnd.F_MULTI) s = ':first-child';

			//operates on assumption that select image is in gallery, needs to be extended for search
			//.replace() escapes periods in our image ids
			var im = $('DIV.filmstrip IMG.' + i_id[0].replace('.','\\.'), sc);
			$('DIV.productSlots LI'+s, sc).each( function () {
				cartAdd._bndAddThmb(im, this);
			});
		} else {
			$('DIV.productSlots LI', sc).each( function (i, e) {
				if (i >= i_id.length) return false; //break out
				var im = $('DIV.filmstrip IMG.' + i_id[i].replace('.','\\.'), sc);
				if (im.length) cartAdd._bndAddThmb(im, this);
			});
		}

		cartAdd._resize();
	},

	_bndItemClearAll: function ()
	{
		//Find image thmb targets to clear. 
		//TODO: Wrap .prodToolBar and .productSlots in single parent DIV for stability?
		var tA = $(this).closest('.prodToolBar').next('.productSlots').find(".imgDropped");
		tA.each(function () { cartAdd._bndDelThmb($(this)); });
	},

	_fsClick: function (e) 
	{
		var sc = cartAdd.bndWin;
		var bt = $(this);
		var pvpw = $('.psFsViewPort',sc).width();
		var ulw = $('.psFsViewPort UL',sc).width();
		var wpos = $('.listwrap',sc).position();
		var nextp = 0;
		if (bt.hasClass('psFsNext') && (wpos.left > -ulw + pvpw)) {
			nextp = Math.max(wpos.left - pvpw, -ulw + pvpw);
			$('.psFsPrev',sc).css('visibility',	 'visible');
			if (nextp == -ulw + pvpw) $('.psFsNext',sc).css('visibility', 'hidden');
		} else if (bt.hasClass('psFsPrev') && (wpos.left < 0)) {
			nextp = Math.min(wpos.left + pvpw, 0);			
			$('.psFsNext',sc).css('visibility',	 'visible');
			if (nextp == 0) $('.psFsPrev',sc).css('visibility', 'hidden');
		}
		$('.listwrap',sc).animate({"left":	nextp + 'px'}, "fast");
	},

	_fqDataUpd: function (d) 
	{	
		var r = {};
		r['RM'] = {
				FUP_ID: 'RM',
				TYPE: 'RM',
				PRICE: 0,
				QTY: 0
			};
		if (d) {
			r['RM'].PRICE = d.FQ_PRICE;	
			r['RM'].QTY = 1;
			r['RM'].IMAGES = [$("#psCpDownloads .psCpDownloadsRm").data("rmImage")];

			// HACK: for RM compat
			var rmd = _bsForm.toArray($("#psCpDownloads .psCpDownloadsRm form.fq").get(0));
			if (rmd.FQ_SUBCAT_SUB && rmd.FQ_SUBCAT == 'subCatSub')
					rmd.FQ_SUBCAT = rmd.FQ_SUBCAT_SUB;

			cartAdd.rmData = rmd;
		}
		cartAdd._dataUpd(r);
	},

	_fqCB: function (type, data, args)
	{		
		switch (args[0]) {
		case 'cancel':
		//this.cancel();
			break;
		case 'setContent': 
			var d = args[1];
			$('#psCpDownloads .psCpDownloadsRm .Price DIV').html(d ? d.PREF_CURRENCY_STR + ' ' + d.FQ_PRICE : ''); 
			cartAdd._fqDataUpd(d);
			break;
		case 'setTerms': $('#psCpDownloads .psCpDownloadsRm .Terms DIV').html(args[1] ? args[1] : ''); break;
		case 'show': 
		/*
			var f_show = (this.curType == 'rm');
			if (isset(args[1])) {
				var img = args[1]['img'];
				var prf = args[1]['prcPrf'];

				this.dltype = prf.PRF_DLTYPE;

				this.hintDIV.innerHTML = '<b>' + BS.utl.string.truncate(img.I_FILE_NAME, 20) + '</b><br>' + img.I_WIDTH + 'x' + img.I_HEIGHT + ' pixels (' + BS.utl.string.fmtBytes(img.I_FILE_SIZE) + ')';
				
				var str = 'Rights-managed usage for this image is restricted to the regions and categories listed below.<br>All licenses are for one year unless otherwise indicated.';

				if (this.dltype.substr(0,4) != 'ORIG')
					str += '<div style="color:red;font-weight:bold;">This image is provided in JPEG format only.</div>';
				
				if (f_show) this.msgDIV.innerHTML = this.rmHead + str;
				this.rmMsg = str;
			}

			//don't know why I need this
			this._showRM(f_show);
		*/
			break;
		 }	 
	},

	_resizeTO: function () 
	{ 
		setTimeout(function () { cartAdd._resize(); },0); 
	},
	_resize: function()
	{
		var cA = cartAdd.win;

		if (cartAdd.bndWin) cartAdd._bndResize();

		if (!$('.psCartAddSumConf').length) {
			var pMain = $("#psCartAddPaneMain");
			//float order is reversed from tab content order
			var selIdx = (pMain.tabs('length')-1) - pMain.tabs('option', 'selected');
			var slide = $("#cartWin DIV .psCartSlide").eq(selIdx);
			var pane, minH, trueH;
			if (slide.prop('id') != 'psCpDownloads') {
				pane = $(".cartAddTbBody", slide);
				minH = $(".psCartAddPaneLt", slide).height();
				trueH = $("form", slide).height();
			} else { //mutate for downloads
				pane = $(".psCpRszTarget:visible", slide);
				if (pane.hasClass("psCpDownloadsChooser") || pane.hasClass("psCpFqCont"))
					minH = trueH = $(".cartAddStaticRuler:visible").height();
				else minH = $(".psCartAddPaneLt:visible", slide).height();
			}
			$().PS.dialogResize(cA, minH, pane);
		}

		cA.dialog("option", "width", 850);

		if (!cartAdd.winState)
			cA.dialog("option", "position", "center");
	},

	_submit: function () 
	{
		var itemA = {};
		var items = cartAdd._data.items;

		for (var fup_id in items) { 
			var type, item = items[fup_id];
			switch (type = item.TYPE.toLowerCase()) {
			case 'rm':

				/* Don't think we have special instructions anymore, need to double check
				if (this.d.info.SPEC_INSTRUCTS) {
					if (!this.f_sIAgreed) {
						this._instSIPrompt();
						var txts = {};
						txts.msgHTML = "<b>ATTENTION</b>: This photographer has included the following special instructions for this image:";
	
						txts.msgHTML += '<p>' + this.d.info.SPEC_INSTRUCTS + '</p>';
	
						txts.msgHTML += "While in many cases this content may be purely informational, in others it may indicate usage restrictions or limited availability of this image. Please pay special attention to the content in the above field, as the photographer retains the right to refund your purchase and void the terms of license if the above is found to have been violated.";
						this.siPrompt.setTxts(txts);
						return this.siPrompt.show(true);
					} else this.f_sIAgreed = false;
				}
	
				if (this.siPrompt) this.siPrompt.show(false);
				*/	
				itemA['rm'] = [];

				//hack ... remap data out of array or jq won't rec it
				//TODO - port _bsForm.toArray to jq to avoid this
				var jqsux = {};
				for (var k in cartAdd.rmData) jqsux[k] = cartAdd.rmData[k];
				jqsux.FQ_SDATE = {};
				for (var k in cartAdd.rmData.FQ_SDATE) jqsux.FQ_SDATE[k] = cartAdd.rmData.FQ_SDATE[k];

				itemA['rm'].push({
					FUP_ID: 'RM',
					IMAGES: item.IMAGES,
					QTY: item.QTY,
					rmData: jqsux
				});

				break;
			case 'bnd':
				itemA['bnd'] = [];
				itemA['bnd'].push({
					FUP_ID: fup_id,
					QTY: item.QTY,
					bndData: cartAdd.bndData
				});
				break;
			default:
				if ((typeof itemA[type]) == 'undefined')
					itemA[type] = [];

				itemA[type].push({
					FUP_ID: fup_id,
					QTY: item.QTY,
					FINISH:	 (item.OPT ? item.OPT : ''),
					IMAGES: item.IMAGES						
				});
			}
		}

		cartAdd.win.html('<div id="cartWin"><div class="psWaitingMd"><img src="/img/icon/ajax-loader-medium.gif" border="0">&nbsp&nbsp;Please wait.</div></div>');
		$(".psWaitingMd").bind("bsapi_error", function() {
			$(this).html('We are unable to process your request at this time.');
		});
		
		$.ajax({
			url: '/ajax/cartAct', 
			type: 'POST', 
			dataType: 'json',
			data: {'_ACT': 'cartItemAdd', 'items': itemA},
			global: true,
			bsapiCB: cartAdd._submitCB
		});
	},

	_submitCB: function (d, s) 
	{
		//replace & remove edited line items and refresh cart-show
		if (typeof cartAdd.initD.FLI_ID == 'string') {
			fli_id = cartAdd.initD.FLI_ID;
			$(".cartAddClose").unbind('click');
			cartAdd.win.unbind('dialogclose');
			$.ajax({
				url: '/ajax/cartAct',
				type: 'POST',
				global: true,
				data: { _ACT: 'cartItemDel', FLI_ID: fli_id },
				bsapiCB: function (d, s) {
					$(".cartAddClose").click(function() {
						cartAdd._nukeWin;
						location = '/cart/';
					});
					cartAdd.win.bind('dialogclose', function() {
						cartAdd._nukeWin;
						location = '/cart/';
					});
					cartAdd._nukeWin;
					cartAdd.win.dialog("close");
				}
			});
			return;
		}

		var n = d.n_item;
		var cart = d.cart;
		var itm = "item"+(n != 1 ? 's' : '' );
		var cartUrl = '/cart?cartAdd=t&srcUrl=' + BS.utl.string.urlencode(window.location);
		var i_id;

		var crnc = cart.FO_CURRENCY_STR;
		
		// find an image for thumbnail
		for (var k in cartAdd._data.items) {
			var t = cartAdd._data.items[k];
			if ((typeof t.IMAGES) != 'undefined')
				i_id = cartAdd._data.items[k].IMAGES[0];
			else
				i_id = cartAdd.bndData[0].I_ID;
			break;
		}

		//cart summary
		var sumItms = [];
		sumItms.push(["Items Subtotal", cart.SUBTOTAL]);

		var k = 'Shipping'; 
		if (cart.CHK_REQ.f_ship_est) k += ' (estimated)';
		sumItms.push([k, cart.FO_SHIPPING ? cart.FO_SHIPPING : '0.00']);

		//sumItms.push(["Discount", "0.00"]);

		if (cart.CHK_REQ.f_tax_est)
			sumItms.push(["Tax", 'TBD']);
		else
			sumItms.push(["Tax", cart.FO_TAX]);

		var str = "<div class='psDialog psCartConf'>";

		confThumb =  $().PS.app('imgGet', i_id, 't/120');
		$.each(cartAdd._data.items, function(k,v){
			$.each(v, function(k,v){
				if (k == 'IMAGES' && v.length > 1) {
					confThumb = '/img/cart/icon/multiple-images.png';
					return;
				 } 
			});
		});

		str += "<div class='psCartConfLeft'>" + 
			"<h1>" + n + " " + itm + " added to <a href='" + cartUrl + "' target='_blank'>Your Cart.</a></h1>" +
			"<div><img src='" + confThumb + "'></div>" + 
			"</div>";

		str += "<div class='psCartConfRight'>" +
			"<h1>Your Cart <a href='" + cartUrl + "' target='_blank'>(" + cart.QTY + " item" + (cart.QTY != 1 ? 's' : '')+")</a></h1>";
		str += '<table class="psCartConfSummary">';
		for (var i = 0, l = sumItms.length; i < l; i++) {
			str += "<tr><th>" + sumItms[i][0] + "</th><td>" + crnc+sumItms[i][1] + "</td></tr>";
		}
		str += '<tr class="total"><th>Total';
		if (cart.CHK_REQ.f_estimated) str += ' (estimated)';
		str += '</th><td>' + crnc + cart.FO_TOTAL + '</td></tr>';
		str += '</table>';
		str += '</div>';
		
		str += '<div class="clear"></div></div>';
		
		str += "<div class='psDialogFooter'><table><tr><td><a href='javascript: void(0);' class='cartAddClose'>Continue Shopping</a></td><td><a href='" + cartUrl + "' id='cartAddCheckout' class='cartButton checkOut f_right'><img src='/img/blank.gif' alt='Check Out'></a></td></tr></table></div>";

		cartAdd.win.html(str);
		$(".cartAddClose").click(cartAdd._nukeWin);
		
		// update cartIcon
		cartIcon.refresh();

	},

	setWin: function (m) { cartAdd.win.dialog(m); }
};

$.fn.PS.cartAdd = function(method) {
	if (cartAdd[method]) {
		return cartAdd[method].apply(this, Array.prototype.slice.call(arguments, 1));
	}
	else if (typeof method === 'object' || !method) {
		return cartAdd.init.apply(this, arguments);
	}
	else {
		$.error('PS.cartAdd: undefined method [' + method + ']');
	}
};

$().ready(function() {
	$(".psCartAddLink, .edit_cart_item").each(function() {
		var cartButton = $(this).bind('click', function() {
			var d = $(this).data('cartAdd');
			if (!d) return false;

			if (d.I_ID) {
				cartAdd._createWin(d);
				cartButton.click(function(evt) {
					cartAdd.setWin('open');
					return false;
				});
			}
			else if (d.G_ID || d.F_SRCH) {
				$().PS.cartAddSel(d)
			}

			return false;
		});
	});

	$(window).unload(function() {
		cartAdd = null;
		cartIcon = null;
		$().find("*").unbind();
		$(document).empty();
	});
});


// ################ cartAddSel ################

//experimental override of ui selectable - all this mess (copied from jQuery UI Selectable 1.8.12) just to add shift select
$.widget('ui.selectablePS', $.extend({}, $.ui.selectable.prototype, {
	_mouseStart: function(event) {
		var self = this;

		this.opos = [event.pageX, event.pageY];

		if (this.options.disabled)
			return;

		var options = this.options;

		this.selectees = $(options.filter, this.element[0]);

		this._trigger("start", event);

		$(options.appendTo).append(this.helper);
		// position helper (lasso)
		this.helper.css({
			"left": event.clientX,
			"top": event.clientY,
			"width": 0,
			"height": 0
		});

		if (options.autoRefresh) {
			this.refresh();
		}

		this.selectees.filter('.ui-selected').each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.startselected = true;
			if (!(event.metaKey || event.shiftKey)) {
				selectee.$element.removeClass('ui-selected');
				selectee.selected = false;
				selectee.$element.addClass('ui-unselecting');
				selectee.unselecting = true;
				// selectable UNSELECTING callback
				self._trigger("unselecting", event, {
					unselecting: selectee.element
				});
			}
		});

		$(event.target).parents().andSelf().each(function() {
			var selectee = $.data(this, "selectable-item");
			if (selectee) {
				var doSelect = !(event.metaKey || event.shiftKey) || !selectee.$element.hasClass('ui-selected');
				selectee.$element
					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
				selectee.unselecting = !doSelect;
				selectee.selecting = doSelect;
				selectee.selected = doSelect;
				// selectable (UN)SELECTING callback
				if (doSelect) {
					self._trigger("selecting", event, {
						selecting: selectee.element
					});
				} else {
					self._trigger("unselecting", event, {
						unselecting: selectee.element
					});
				}
				return false;
			}
		});

	},

	_mouseDrag: function(event) {
		var self = this;
		this.dragged = true;

		if (this.options.disabled)
			return;

		var options = this.options;

		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});

		this.selectees.each(function() {
			var selectee = $.data(this, "selectable-item");
			//prevent helper from being selected if appendTo: selectable
			if (!selectee || selectee.element == self.element[0])
				return;
			var hit = false;
			if (options.tolerance == 'touch') {
				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
			} else if (options.tolerance == 'fit') {
				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
			}

			if (hit) {
				// SELECT
				if (selectee.selected) {
					selectee.$element.removeClass('ui-selected');
					selectee.selected = false;
				}
				if (selectee.unselecting) {
					selectee.$element.removeClass('ui-unselecting');
					selectee.unselecting = false;
				}
				if (!selectee.selecting) {
					selectee.$element.addClass('ui-selecting');
					selectee.selecting = true;
					// selectable SELECTING callback
					self._trigger("selecting", event, {
						selecting: selectee.element
					});
				}
			} else {
				// UNSELECT
				if (selectee.selecting) {
					if ((event.metaKey || event.shiftKey) && selectee.startselected) {
						selectee.$element.removeClass('ui-selecting');
						selectee.selecting = false;
						selectee.$element.addClass('ui-selected');
						selectee.selected = true;
					} else {
						selectee.$element.removeClass('ui-selecting');
						selectee.selecting = false;
						if (selectee.startselected) {
							selectee.$element.addClass('ui-unselecting');
							selectee.unselecting = true;
						}
						// selectable UNSELECTING callback
						self._trigger("unselecting", event, {
							unselecting: selectee.element
						});
					}
				}
				if (selectee.selected) {
					if (!(event.metaKey || event.shiftKey) && !selectee.startselected) {
						selectee.$element.removeClass('ui-selected');
						selectee.selected = false;

						selectee.$element.addClass('ui-unselecting');
						selectee.unselecting = true;
						// selectable UNSELECTING callback
						self._trigger("unselecting", event, {
							unselecting: selectee.element
						});
					}
				}
			}
		});

		return false;
	},

	_mouseStop: function(event) {
		var self = this;

		//adds conventional shift-select
		if (this.dragged == false && event.shiftKey && isset(this.lastClickInd) ) {
			var thisClick = $('.ui-selecting', this.element[0]).index();
			var start, end;
			if (thisClick < this.lastClickInd) {
				start = thisClick, end = this.lastClickInd;
			} else {
				start = this.lastClickInd, end = thisClick;
			}
			this.selectees.slice(start, end+1).each(function () {
				var selectee = $.data(this, "selectable-item");
				selectee.$element.addClass('ui-selecting');
				selectee.selecting = true;
				// selectable SELECTING callback
				self._trigger("selecting", event, {
						selecting: selectee.element
										});
			});
		} else {
			var selectEl = $('.ui-selecting', this.element[0]);
			if (selectEl.length) this.lastClickInd = $('.ui-selecting', this.element[0]).index();
		}
		this.dragged = false;

		var options = this.options;

		$('.ui-unselecting', this.element[0]).each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.$element.removeClass('ui-unselecting');
			selectee.unselecting = false;
			selectee.startselected = false;
			self._trigger("unselected", event, {
				unselected: selectee.element
			});
		});
		$('.ui-selecting', this.element[0]).each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
			selectee.selecting = false;
			selectee.selected = true;
			selectee.startselected = true;
			self._trigger("selected", event, {
				selected: selectee.element
			});
		});
		this._trigger("stop", event);

		this.helper.remove();

		return false;
	}
}));

$.fn.PS.cartAddSel = function(d) {
	var obj = $("#psCartAddSel");

	if (obj.length)
		return obj.cartAddSel('open');

	$('<div id="psCartAddSel"><div class="psWaitingMd"><img src="/img/icon/ajax-loader-medium.gif" border="0">&nbsp&nbsp;Please wait.</div></div>').data('cartAddData', d).cartAddSel({initData: d});
};

$.widget('ps.cartAddSel', {
	_create: function () {
		var obj = this.element;
		var d = this.options.initData;
	 	var thmburl = 'http://' + location.host + location.pathname + '?select=t';
		if (d.F_SRCH) thmburl += '&_bqH=' + d.F_SRCH_H;
		
		obj.dialog({
			position: 'center',
			autoOpen: true,	//for performance, bleh.
			modal: true,
			width: 450,
			height: 'auto',
			title: 'Add images to shopping cart',
			dialogClass: 'ps psCartAddSel',
			resizable: false
		});

		if (this._loadPage(thmburl))
			$(window).resize(this, function(e) { e.data._resize.apply(e.data, arguments); });
	},

	_wirePage: function () {
		var obj = $("#psCartAddSel");
		var sel = obj.find("DIV.thumbwrap DIV");		
		sel.selectablePS({filter: 'li', cancel: 'ul.batchthumbs li.disabled'});
		
		//$('#psCartAddSel .thumbwrap')[0].scrollTop = $('#psCartAddSel .pagStart').position().top;
		$('#cartAddBatchSelectAll').live('click', this.selectAll);
		$('#cartAddBatchClear').live('click', this.clear);
		$('#cartAddBatchNext').live('click', this.makeSelection);
		$('#cartAddBatchCancel').live('click', this.close);

		obj.find('select').first().attr('onchange',null).bind('change', this.pagChange);
		obj.find('a.page_previous, a.page_next').bind('click', this.pagLink);
		obj.dialog("open");

		var st = $('#psCartAddSel .pagStart').position().top;
		$('#psCartAddSel .thumbwrap').scrollTop(st);

		$('#psCartAddSel .thumbwrap').live('set_scroll_top', function() {
			$('#psCartAddSel .thumbwrap').scrollTop($('#psCartAddSel .pagStart').position().top); 
		});

		this._resize(null, st);
		//scrollTop cannot be set from within thread due to latent rendering
		$.event.trigger('set_scroll_top');
	},
	
	_setScrollTop: function()
	{
		$('#psCartAddSel .thumbwrap').scrollTop($('#psCartAddSel .pagStart').position().top); 
	},

	_loadPage: function (url) {
		//this.element.empty();
		//this.element.append($('<div>please wait...</div>'));

		//leaky! need to find a way to pass scope on this
		var that = this;
		var loader = this.element.load(url, function () {
			if ($('#psCartAddSel .pagStart').length == 0) {
				$('#cartAddBatchCancel').bind('click', that.close);
				return false;
			}

			that._wirePage.apply(that, arguments)
			that = null;
		});
		return true;
	},

	_resize: function (e, st) {
		var seldialog = $("#psCartAddSel");
		var tr = $("#psCartAddSel DIV.thumbwrap");
		var thmbH = tr.first().height();

		$().PS.dialogResize(seldialog, $("#psCartAddSel DIV.thumbwrap LI").height(), tr);

		seldialog.dialog("option", "width", 850);
		seldialog.dialog("option", "position", "center");
	},

	selectAll: function () {
		$("#psCartAddSel UL.batchthumbs LI").addClass('ui-selected');			 
	},

	clear: function () {
		$("#psCartAddSel UL.batchthumbs LI").removeClass('ui-selected');			 
	},

	makeSelection: function () {
		var data = $("#psCartAddSel").data('cartAddData');
		var els = $("#psCartAddSel LI.ui-selected").not('.disabled');

		if (!els.length)
			return alert("Please select at least one image.");

		var d = {I_ID: []};
		if (data.G_ID) d.G_ID = data.G_ID;

		// limit selection to 100 images
		if (els.length > 100) {
			alert("You have selected " + els.length + " images, but you can only add up to 100 at a time. Please try again!");
			return;
		}
		
		for (var i = 0, l = els.length; i < l; i++)
			d.I_ID.push($(els[i]).data('cartAdd').I_ID);

		$("#psCartAddSel").dialog("close");
		cartAdd._createWin(d);
	},					 

	pagChange: function (jqe) {
		var p = $(jqe.target).val();
		var l, url, urlA = location.href.split('/');
		if ((l = urlA.slice(-1)) && !isNaN(parseInt(l[0]))) url = urlA.slice(0,-1).join('/') + '/';
		else if (!l) url = urlA.join('/');
		else url = urlA.join('/') + '/';
		url += p + '?select=t'; 
		$("#psCartAddSel").cartAddSel('loadPage', url);
	},

	pagLink: function (jqe) {
		jqe.preventDefault();
		$("#psCartAddSel").cartAddSel('loadPage', jqe.target.href + '?select=t');
		return false;
	},

	open: function () {
		this.element.dialog("open");			 
	},

	close: function () {
		$("#psCartAddSel").dialog("close");
	}
});

})(ps$);

// HACK: for iframe access (cross-domain hack)
var _cartIconUpdate = function (doc, n) { ps$(doc).PS.cartIcon('_update', n); }

