(function(p){var q="string",w="head",L="body",M="script",u="readyState",j="preloaddone",x="loadtrigger",N="srcuri",E="preload",Z="complete",y="done",z="which",O="preserve",F="onreadystatechange",ba="onload",P="hasOwnProperty",bb="script/cache",Q="[object ",bw=Q+"Function]",bx=Q+"Array]",e=null,h=true,i=false,k=p.document,bc=p.location,bd=p.ActiveXObject,A=p.setTimeout,be=p.clearTimeout,R=function(a){return k.getElementsByTagName(a)},S=Object.prototype.toString,G=function(){},r={},T={},bf=/^[^?#]*\//.exec(bc.href)[0],bg=/^\w+\:\/\/\/?[^\/]+/.exec(bf)[0],by=R(M),bh=p.opera&&S.call(p.opera)==Q+"Opera]",bi=("MozAppearance"in k.documentElement.style),bj=(k.createElement(M).async===true),v={cache:!(bi||bh),order:bi||bh||bj,xhr:h,dupe:h,base:"",which:w};v[O]=i;v[E]=h;r[w]=k.head||R(w);r[L]=R(L);function B(a){return S.call(a)===bw}function U(a,b){var c=/^\w+\:\/\//,d;if(typeof a!=q)a="";if(typeof b!=q)b="";d=((/^\/\//.test(a))?bc.protocol:"")+a;d=(c.test(d)?"":b)+d;return((c.test(d)?"":(d.charAt(0)==="/"?bg:bf))+d)}function bz(a){return(U(a).indexOf(bg)===0)}function bA(a){var b,c=-1;while(b=by[++c]){if(typeof b.src==q&&a===U(b.src)&&b.type!==bb)return h}return i}function H(t,l){t=!(!t);if(l==e)l=v;var bk=i,C=t&&l[E],bl=C&&l.cache,I=C&&l.order,bm=C&&l.xhr,bB=l[O],bC=l.which,bD=l.base,bn=G,J=i,D,s=h,m={},K=[],V=e;C=bl||bm||I;function bo(a,b){if((a[u]&&a[u]!==Z&&a[u]!=="loaded")||b[y]){return i}a[ba]=a[F]=e;return h}function W(a,b,c){c=!(!c);if(!c&&!(bo(a,b)))return;b[y]=h;for(var d in m){if(m[P](d)&&!(m[d][y]))return}bk=h;bn()}function bp(a){if(B(a[x])){a[x]();a[x]=e}}function bE(a,b){if(!bo(a,b))return;b[j]=h;A(function(){r[b[z]].removeChild(a);bp(b)},0)}function bF(a,b){if(a[u]===4){a[F]=G;b[j]=h;A(function(){bp(b)},0)}}function X(b,c,d,g,f,n){var o=b[z];A(function(){if("item"in r[o]){if(!r[o][0]){A(arguments.callee,25);return}r[o]=r[o][0]}var a=k.createElement(M);if(typeof d==q)a.type=d;if(typeof g==q)a.charset=g;if(B(f)){a[ba]=a[F]=function(){f(a,b)};a.src=c;if(bj){a.async=i}}r[o].insertBefore(a,(o===w?r[o].firstChild:e));if(typeof n==q){a.text=n;W(a,b,h)}},0)}function bq(a,b,c,d){T[a[N]]=h;X(a,b,c,d,W)}function br(a,b,c,d){var g=arguments;if(s&&a[j]==e){a[j]=i;X(a,b,bb,d,bE)}else if(!s&&a[j]!=e&&!a[j]){a[x]=function(){br.apply(e,g)}}else if(!s){bq.apply(e,g)}}function bs(a,b,c,d){var g=arguments,f;if(s&&a[j]==e){a[j]=i;f=a.xhr=(bd?new bd("Microsoft.XMLHTTP"):new p.XMLHttpRequest());f[F]=function(){bF(f,a)};f.open("GET",b);f.send("")}else if(!s&&a[j]!=e&&!a[j]){a[x]=function(){bs.apply(e,g)}}else if(!s){T[a[N]]=h;X(a,b,c,d,e,a.xhr.responseText);a.xhr=e}}function bt(a){if(typeof a=="undefined"||!a)return;if(a.allowDup==e)a.allowDup=l.dupe;var b=a.src,c=a.type,d=a.charset,g=a.allowDup,f=U(b,bD),n,o=bz(f);if(typeof d!=q)d=e;g=!(!g);if(!g&&((T[f]!=e)||(s&&m[f])||bA(f))){if(m[f]!=e&&m[f][j]&&!m[f][y]&&o){W(e,m[f],h)}return}if(m[f]==e)m[f]={};n=m[f];if(n[z]==e)n[z]=bC;n[y]=i;n[N]=f;J=h;if(!I&&bm&&o)bs(n,f,c,d);else if(!I&&bl)br(n,f,c,d);else bq(n,f,c,d)}function Y(a){if(t&&!I)K.push(a);if(!t||C)a()}function bu(a){var b=[],c;for(c=-1;++c<a.length;){if(S.call(a[c])===bx)b=b.concat(bu(a[c]));else b[b.length]=a[c]}return b}D={script:function(){be(V);var a=bu(arguments),b=D,c;if(bB){for(c=-1;++c<a.length;){if(B(a[c]))a[c]=a[c]();if(c===0){Y(function(){bt((typeof a[0]==q)?{src:a[0]}:a[0])})}else b=b.script(a[c]);b=b.wait()}}else{for(c=-1;++c<a.length;){if(B(a[c]))a[c]=a[c]()}Y(function(){for(c=-1;++c<a.length;){bt((typeof a[c]==q)?{src:a[c]}:a[c])}})}V=A(function(){s=i},5);return b},wait:function(a){be(V);s=i;if(!B(a))a=G;var b=H(t||J,l),c=b.trigger,d=function(){try{a()}catch(err){}c()};delete b.trigger;var g=function(){if(J&&!bk)bn=d;else d()};if(t&&!J)K.push(g);else Y(g);return b}};if(t){D.trigger=function(){var a,b=-1;while(a=K[++b])a();K=[]}}else D.trigger=G;return D}function bv(a){var b,c={},d={"UseCachePreload":"cache","UseLocalXHR":"xhr","UsePreloading":E,"AlwaysPreserveOrder":O,"AllowDuplicates":"dupe"},g={"AppendTo":z,"BasePath":"base"};for(b in d)g[b]=d[b];c.order=!(!v.order);for(b in g){if(g[P](b)&&v[g[b]]!=e)c[g[b]]=(a[b]!=e)?a[b]:v[g[b]]}for(b in d){if(d[P](b))c[d[b]]=!(!c[d[b]])}if(!c[E])c.cache=c.order=c.xhr=i;c.which=(c.which===w||c.which===L)?c.which:w;return c}p.$LAB={setGlobalDefaults:function(a){v=bv(a)},setOptions:function(a){return H(i,bv(a))},script:function(){return H().script.apply(e,arguments)},wait:function(){return H().wait.apply(e,arguments)}};(function(a,b,c){if(k[u]==e&&k[a]){k[u]="loading";k[a](b,c=function(){k.removeEventListener(b,c,i);k[u]=Z},i)}})("addEventListener","DOMContentLoaded")})(window);

function jsonPath(obj,expr,arg){var P={resultType:arg&&arg.resultType||"VALUE",result:[],normalize:function(expr){var subx=[];return expr.replace(/[\['](\??\(.*?\))[\]']/g,function($0,$1){return"[#"+(subx.push($1)-1)+"]";}).replace(/'?\.'?|\['?/g,";").replace(/;;;|;;/g,";..;").replace(/;$|'?\]|'$/g,"").replace(/#([0-9]+)/g,function($0,$1){return subx[$1];});},asPath:function(path){var x=path.split(";"),p="$";for(var i=1,n=x.length;i<n;i++)
p+=/^[0-9*]+$/.test(x[i])?("["+x[i]+"]"):("['"+x[i]+"']");return p;},store:function(p,v){if(p)P.result[P.result.length]=P.resultType=="PATH"?P.asPath(p):v;return!!p;},trace:function(expr,val,path){if(expr){var x=expr.split(";"),loc=x.shift();x=x.join(";");if(val&&val.hasOwnProperty(loc))
P.trace(x,val[loc],path+";"+loc);else if(loc==="*")
P.walk(loc,x,val,path,function(m,l,x,v,p){P.trace(m+";"+x,v,p);});else if(loc===".."){P.trace(x,val,path);P.walk(loc,x,val,path,function(m,l,x,v,p){typeof v[m]==="object"&&P.trace("..;"+x,v[m],p+";"+m);});}
else if(/,/.test(loc)){for(var s=loc.split(/'?,'?/),i=0,n=s.length;i<n;i++)
P.trace(s[i]+";"+x,val,path);}
else if(/^\(.*?\)$/.test(loc))
P.trace(P.eval(loc,val,path.substr(path.lastIndexOf(";")+1))+";"+x,val,path);else if(/^\?\(.*?\)$/.test(loc))
P.walk(loc,x,val,path,function(m,l,x,v,p){if(P.eval(l.replace(/^\?\((.*?)\)$/,"$1"),v[m],m))P.trace(m+";"+x,v,p);});else if(/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc))
P.slice(loc,x,val,path);}
else
P.store(path,val);},walk:function(loc,expr,val,path,f){if(val instanceof Array){for(var i=0,n=val.length;i<n;i++)
if(i in val)
f(i,loc,expr,val,path);}
else if(typeof val==="object"){for(var m in val)
if(val.hasOwnProperty(m))
f(m,loc,expr,val,path);}},slice:function(loc,expr,val,path){if(val instanceof Array){var len=val.length,start=0,end=len,step=1;loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g,function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);});start=(start<0)?Math.max(0,start+len):Math.min(len,start);end=(end<0)?Math.max(0,end+len):Math.min(len,end);for(var i=start;i<end;i+=step)
P.trace(i+";"+expr,val,path);}},eval:function(x,_v,_vname){try{return $&&_v&&eval(x.replace(/@/g,"_v"));}
catch(e){throw new SyntaxError("jsonPath: "+e.message+": "+x.replace(/@/g,"_v").replace(/\^/g,"_a"));}}};var $=obj;if(expr&&obj&&(P.resultType=="VALUE"||P.resultType=="PATH")){P.trace(P.normalize(expr).replace(/^\$;/,""),obj,"$");return P.result.length?P.result:false;}}


(function($){$.toJSON=function(o)
{if(typeof(JSON)=='object'&&JSON.stringify)
return JSON.stringify(o);var type=typeof(o);if(o===null)
return"null";if(type=="undefined")
return undefined;if(type=="number"||type=="boolean")
return o+"";if(type=="string")
return $.quoteString(o);if(type=='object')
{if(typeof o.toJSON=="function")
return $.toJSON(o.toJSON());if(o.constructor===Date)
{var month=o.getUTCMonth()+1;if(month<10)month='0'+month;var day=o.getUTCDate();if(day<10)day='0'+day;var year=o.getUTCFullYear();var hours=o.getUTCHours();if(hours<10)hours='0'+hours;var minutes=o.getUTCMinutes();if(minutes<10)minutes='0'+minutes;var seconds=o.getUTCSeconds();if(seconds<10)seconds='0'+seconds;var milli=o.getUTCMilliseconds();if(milli<100)milli='0'+milli;if(milli<10)milli='0'+milli;return'"'+year+'-'+month+'-'+day+'T'+
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
if(o.constructor===Array)
{var ret=[];for(var i=0;i<o.length;i++)
ret.push($.toJSON(o[i])||"null");return"["+ret.join(",")+"]";}
var pairs=[];for(var k in o){var name;var type=typeof k;if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;if(typeof o[k]=="function")
continue;var val=$.toJSON(o[k]);pairs.push(name+":"+val);}
return"{"+pairs.join(", ")+"}";}};$.evalJSON=function(src)
{if(typeof(JSON)=='object'&&JSON.parse)
return JSON.parse(src);return eval("("+src+")");};$.secureEvalJSON=function(src)
{if(typeof(JSON)=='object'&&JSON.parse)
return JSON.parse(src);var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};$.quoteString=function(string)
{if(string.match(_escapeable))
{return'"'+string.replace(_escapeable,function(a)
{var c=_meta[a];if(typeof c==='string')return c;c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};var _escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var _meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};})(jQuery);

/*
BrowseBox 2.0
It's a proper object now. 
The core object just does page filtering, pagination management, and display.
You then extend the object with more advanced UI management. 
Some common cases are included: clicking to filter, changing ui elements on the page, handling select list filters
All page manipulation has no hard-coded expectations (pagination has a set attribute name it looks for and is handled by the object for proper timing).
Updated extended HTML attributes to be HTML5 complaiant.
Still to do: error trapping/handling. For now, it at least fails silently.
*/

BrowseBox= function(args) {
//properties
this.webServiceURL = args.webServiceURL || null; //The web service for data
this.itemObject= args.itemObject || null; //The object from a web service result that contains the items to iterate over for card generation
this.cardArea= args.cardArea || null; //Jquery selector where the UL of cards will be inserted
this.paginationArea= args.paginationArea || null; //Jquery selector for where pagination text (x of y) will be updated
this.maxRows = args.maxRows || 12; //How many rows/cards to fetch at a time
this.currentFilter = args.currentFilter || {}; //Sets the initial filter conditions
this.defaultCardTemplate = buildDefaultCard; //You can set your own default template if the current template isn't found or valid
this.currentCardTemplate = args.currentCardTemplate || this.defaultCardTemplate; //Sets the inital card template to use
this.postCardFunction = args.postCardFunction || null; //I think I can deprecate this by using $live() instead
this.DATA = null; //A copy of the data from the last web service call is stored here for public access
var totalRows = this.maxRows;
var page = 1;
var totalPages = 1;
var that= this;

//methods

this.go= function(callback) {
	cardPage(callback);
}

function cardPage(callback) {
	var startrow = ((page - 1) * that.maxRows) + 1
	$.getJSON(that.webServiceURL + "?sellerid=84&startrow=" + startrow + "&maxrows=" + that.maxRows + filterToQuerytring(), "", function (data, status) {
		that.DATA = data;
		if (data[that.itemObject]) {
			var items = data[that.itemObject]; //hard-coded expectation
			layoutCards(items);
			totalRows = data.TotalRows;
			paginationText();
			if (typeof callback== 'function') callback();
			}
		});
}

function layoutCards(items) {
	var pc, ca, ul;
	ca= that.cardArea;
	ul= $('<ul></ul>').appendTo($(ca).empty());
	if (items.length <= 0) {
		$(ul).append('<li><h1>No items found.</h1></li>')
	} else {
		for (var p = 0; p < items.length; p++) {
			if (typeof that.currentCardTemplate == 'function') {
				pc = that.currentCardTemplate(items[p]);
			} else {
				pc = that.defaultCardTemplate(items[p]);
			}
		$(pc).appendTo(ul);
		}
		if($("span.badgearea").hasClass("badge-Solution")) {$("span.badgearea.badge-Solution").prev("span").children("a").append("<span>*</span>");}
	}
	if (typeof(that.postCardFunction) == 'function') 
		that.postCardFunction.call();
}

function buildDefaultCard(item) {
	var card = '<li style="overflow:scroll;">' + $.toJSON(item) + '</li>';
	return card;
}

this.turnPage= function(e) {
	var el;
	if (el = e.target.getAttribute('data-pagination')) {
		if (el == 'next' && page != totalPages) {
			page++;
		}
		if (el == 'prev' && page > 1) {
			page--;
		}
	cardPage();
	paginationText();
	}
	return false;
}

this.filterPage= function(opts) {
	currentFilter = {};
	for (var x in opts) {
		that.currentFilter[x] = opts[x];
	}
	page = 1;
	totalPages = 1;
	cardPage();
}

function paginationText() {
	totalPages = Math.ceil(totalRows / that.maxRows);
	totalPages = (totalPages <= 0) ? 1 : totalPages;

	$('.BBpagination_control').show();
	if(totalPages>1)
	{	
		$(that.paginationArea).html(page + ' of ' + totalPages);
	}
	else
	{
		$('.BBpagination_control').hide();
	}
}

function filterToQuerytring() {
	var qs = '', val;
	for (var x in that.currentFilter) {
		val = that.currentFilter[x];
		if (val.length > 0) {
			qs = qs + '&' + x + '=' + val;
		}
	}
	return qs;
}

this.querystringToJSON= function() {
	var json = {}, qsa, ta;
	if (window.location.search.length>0) {
		qsa = window.location.search.substring(1).split('&');
		for (var a = 0; a < qsa.length; a++) {
			ta = qsa[a].split('=');
			json[ta[0]] = ta[1];
		}
	}
	return json;
}

}//closes the constructor


//These methods extend browsebox to add custom UI behavior.

BrowseBox.prototype.clickFilter= function(e) {
	var tem, fob= this.currentFilter, df;
	//this.currentCardTemplate = null;
	if (tem = $(e.target).attr('data-template')) 
		this.currentCardTemplate = window[tem]; //Don't like this. Shouldn't assume templates will be in global.
	if (df = $(e.target).attr('data-filter')) {
		df = df.replace(/'/gi, "\"");
		df = jQuery.parseJSON(df);
		for (var f in df) {
		fob[f]= df[f];
		}
		this.filterPage(fob);
	}
	$(e.target).parent().siblings().removeClass('ui-state-active');
	$(e.target).parent().addClass('ui-state-active');
	return false;
}
BrowseBox.prototype.sideTab= function(e) {
	var cc, ui;
	this.clickFilter(e);
	$("ul.bb-tabs li").removeClass("active");
	$(e.target).parent('li').addClass("active");
	if (cc = $(e.target).attr('data-cardclass')) {
		$(this.cardArea).removeClass().addClass(cc);
	}
	$('.filter_container').addClass('hide');
	if (ui = $(e.target).attr('data-ui')) {
		$('#' + ui).removeClass('hide');
		$('#' + ui + ' :input').each(function () {
				$(this).val('');
			});
		this.initForm(ui,this);
	}
	return false;
}
BrowseBox.prototype.initForm= function(con,that) {
	var initFunc;
	$('#' + con + ' :input').each(function () {
			if (initFunc = $(this).attr('data-init')) {
				that[initFunc]($(this).attr('id'));
			}
		});
}

BrowseBox.prototype.selectChange= function(e) {
	var sels = $(e.target).siblings('select').andSelf();
	var fob= this.currentFilter;
	sels.each(function() {
			fob[$(this).attr('name')] = $(this).val();
		});
	this.filterPage(fob);	
}

BrowseBox.prototype.buildSubcatSelect= function(elid) {
	var cat, opts, sel;
	if (cat = this.currentFilter.category) {
		opts = jsonPath(this.DATA, "$.Categories.Options[?(@.ControllingValue=='" + cat + "')].DependentOptions");
		opts = opts[0];
		sel = $('#' + elid);
		sel.empty().append('<option value=\"\" selected=\"selected\">Subcategory</option>');
		for (var o = 0; o < opts.length; o++) {
			sel.append('<option value=\"' + opts[o] + '\">' + opts[o] + '</option>');
		}
	}
}

BrowseBox.prototype.itemCounts= function() { //adds item counts to side tab filters
$('.bb-tabs li').each(function(){

var fil= $.parseJSON($(this).attr('data-filter'));
if (fil.category) {
	 //look up the item count in the data and display?
	 }

});
}

BrowseBox.prototype.updateButton= function() {
	var sels = $('#collateral-filter select');
	var fob= this.currentFilter;
	var sv, sn;
	sels.each(function() {
		sv= $(this).val();
		sn= $(this).attr('name');
		if (sv instanceof Array && sv[0].length>0) {
			fob[sn] = sv;
			}		
		else if (typeof sv== 'string' && sv.length>0 ) {
			fob[sn] = sv;
			}
		else {
			fob[sn]= "";
			}
		});
	this.filterPage(fob);	
}



function loadBB() {
$('#browsebox').load('/portals/38/scripts/browsebox_dt.html', function(){initBrowseBox()});
}
//Initialization and card script for the home page browse box
function buildProductCard(prod) {
	card = '<li><span class="certified '+prod.Certified+'">&#160;</span><a href="/tools/Product.aspx?id=' + prod.ProductID + '" alt="Link to Product Page"><h3>'+ prod.ProductName +'</h3></a>';
	card += '<a href="/tools/Product.aspx?id=' + prod.ProductID + '" alt="Link to Product Page"><img class="tab_content_logo" src="/wdata/product/imagelogo/' + prod.ProductID +'"/></a>';
	card += '<p class="seller-name">'+ trimStr(prod.SellerName,24) +'</p>';
	card += '<span class="otherinfo">'+ prod.DownloadCount +' Downloads | '+ prod.ReviewCount +' Reviews</span>';
	card += '<div class="browse-rating browse-rating-' + prod.Rating + '">&nbsp;</div><br/>';
	card += '<span id="priceContainer" class="price-container"><a class="price-text" href="/tools/Product.aspx?id=' + prod.ProductID + '">$'+ prod.ListPrice +'</a></span>';
	card += '<span class="badgearea badge-'+prod.Type+'"></span></li>';
	return card;

}

function trimStr(str, lengthStr)  {
	if(str.length > lengthStr) {
	    str= str.substring(0,lengthStr - 3)+"...";
	}
	return str;
}

function initBrowseBox() {//initialize event handlers and first page request
bb= new BrowseBox({
webServiceURL: '/wdata/gxy/products/searchjson', 
itemObject: 'Items',
cardArea: '#cardHolder',
maxRows: 12,
currentFilter: {'SellerID':'84'},
paginationArea: '.BBpagination_text',
defaultCardTemplate: buildProductCard,
currentCardTemplate: buildProductCard
})
$(document).ready(function() {
var qsj= bb.querystringToJSON();
if (qsj.hasOwnProperty('documenttype')) {
	$('#collateral-menu a[data-filter*="'+unescape(qsj.documenttype)+'"]').parent().addClass('ui-state-active');
	}

$('#cardHolder').ajaxStart(function(){$(this).empty().prepend('<div id="bbloading"></div>');});	
	
bb.currentFilter= qsj;
bb.go();  //make it go. The function can take a callback.
//UI event handlers
/*IMPORTANT!!! 
You can't just assign a method that used prototype to extend browsebox directly to the event handler.
You have to wrap it in a function that passes the event object on or it won't fire correctly.
*/

$('.BBpagination_control a').click(function(e){bb.turnPage(e);return false});
$('.filter_container a').click(function(e){bb.clickFilter(e);return false});	
$('ul.bb-tabs li a').click(function(e){bb.sideTab(e); return false});

$('#collateral-menu ul li a').click(function(e){bb.clickFilter(e);return false;}); //clickFilter is an extension via prototype
$('.filter_container select').change(function(e){bb.selectChange(e);return false;});
$('#update').click(function(){bb.updateButton();});
 

});
}

