﻿JSON={};
JSON.callbacks=[];
JSON.debug=false;
JSON.temp=null;

JSON.toJSON=function(obj){
	if(obj==null){return null;}
	switch(typeof(obj)){
		case "string":return "\""+obj.replace("\"","\\\"")+"\"";
		case "number":return obj.toString();
		case "boolean":return (obj)?"true":"false";
		case "function":return null;
		case "object":
			var o="";
			if(obj.getDate){return "new Date("+obj.valueOf()+")";}
			if(obj&&typeof(obj.length)=="number"&&obj[0]){
				for(var i=0;i<obj.length;i++){
					if(o!=""){o+=",";}
					o+=JSON.toJSON(obj[i]);
				}
				return "["+o+"]";
			}
			//if(obj.toFixed){return Number(obj);}
			var t="";
			for(var a in obj){
				if(typeof(obj[a])!="function"){
					if(o!=""){o+=",";}
					o+="\""+a+"\":"+JSON.toJSON(obj[a]);
				}
			}
			return "{"+o+"}";
	}
	return null;
}

JSON.fromJSON=function(str){
	eval("JSON.temp="+str);
	var o=JSON.temp;
	JSON.temp=null;
	return o;
}

JSON.invoke=function(svr,method,args,fn){
	if(typeof(fn)!="function"){fn=function(){};}
	var index=(JSON.callbacks.push(fn)-1);
	
	var qs="";
	for(var name in args){
		qs+="&"+name+"="+escape(JSON.toJSON(args[name]));
	}
	url=svr+"/"+method+"?jsonp=JSON.callbacks["+index+"]"+qs;
	JSON.invokeUrl(url);
}

JSON.invokeUrl=function(url){
	if(!url){return false;}
	if(JSON.debug){window.open(url);}
	JSON.addElement(JSON.getHead(),"script",{id:"JSONLoader",src:url,language:"javascript",type:"text/javascript"}," ");
	return true;
}

JSON.getHead=function(){
	var h=document.body;
	var hd=document.getElementsByTagName("head");
	if(hd&&hd[0]){h=hd[0];}
	return h;
}

JSON.createPackage=function(ns){
	var parts=ns.split(".");
	var root=window;
	for(var i=0;i<parts.length;i++){
		if(root[parts[i]]==null||typeof(root[parts[i]])=="undefined"){root[parts[i]]=new Object();}
		root=root[parts[i]];
	}
	return root;
}

JSON.makeElement=function(tn,attr,html,parent){
	if(tn==null){
		var el=document.createTextNode(html);
	}else{
		if(typeof(tn)=="string"){
			var el=document.createElement(tn);
		}else{
			if(tn.tn){var el=tn;}else{return;}
		}
		if(attr){
			for(var a in attr){
				var o=attr[a];
				if(typeof(o)!="function"){
					switch(a.toLowerCase()){
						case "class":el.className=o;break;
						case "colspan":el.colSpan=o;break;
						default:el.setAttribute(a,o);break;
					}
				}
			}
		}
		if(html!=null){
			if(html.tn!=null){el.appendChild(html);}else{try{el.innerHTML=html;}catch(ex){}}
		}
	}
	if(parent!=null){parent.appendChild(el);}
	return el;
}

JSON.addElement=function(node,tn,attr,html){
	var el=JSON.makeElement(tn,attr,html);
	if(!node){node=document.body;}
	node.appendChild(el);
	return el;
}

Function.prototype.toJSON=function(){
	return JSON.toJSON(this);
}

Object.prototype.toJSON=function(){
	return JSON.toJSON(this);
}

String.prototype.trim=function(){
  var x=this;
  x=x.replace(/^\s*(.*)/,"$1");
  x=x.replace(/(.*?)\s*$/,"$1");
  return x;
}
String.prototype.unescape=function(){
	if(this!=null&&this==""){return null;}
	return unescape(this);
}
String.prototype.contains=function(value,ignoreCase){
	var src=this;
	if(ignoreCase){src=src.toLowerCase();value=value.toLowerCase();}
	return (src.indexOf(value)>-1);
}
String.prototype.startsWith=function(value,ignoreCase){
	var src=this;
	if(ignoreCase){src=src.toLowerCase();value=value.toLowerCase();}
	return (src.indexOf(value)==0);
}
String.prototype.endsWith=function(value,ignoreCase){
	var src=this;
	if(ignoreCase){src=src.toLowerCase();value=value.toLowerCase();}
	var at=src.lastIndexOf(value);
	if(at<0){return false;}
	if((at+value.length)==src.length){return true;}return false;
}
String.prototype.replaceAll=function(searchFor,replaceWith,ignoreCase){
	var f="g";if(ignoreCase){f+="i";}
	var re=new RegExp(searchFor,f);
	return this.replace(re,replaceWith);
}
String.prototype.equals=function(val,ignoreCase){
	if(val==null){return false;}
	var src=this;
	if(ignoreCase){src=src.toLowerCase();val=val.toLowerCase();}
	return (src==val);
}
String.prototype.pad=function(len,c,left){
	if(typeof(c)=="undefined"){c=" ";}
	var s=this+"";
	while(s.length<len){if(left){s+=c}else{s=c+s;}}
	return s;
}

Number.prototype.substring=function(start,len){return (this+"").substring(start,len);}
Number.prototype.pad=String.prototype.pad;

Date.prototype.months=["January","February","March","April","May","June","July","August","September","October","November","December"];
Date.prototype.dayOfWeek=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];

Date.prototype.getMonthName=function(abbv){
	var o=this.months[this.getMonth()];
	if(abbv){o=o.substring(0,3);}
	return o;
}
Date.prototype.getDayOfWeek=function(abbv,d){
	if(d==null||d<0||d>6){d=this.getDay();}
	var o=this.dayOfWeek[d];
	if(abbv!=null){
		var len=3;if(typeof(abbv)=="number"){len=abbv;}
		o=o.substring(0,len);
	}
	return o;
}
Date.prototype.clone=function(){
	return new Date(this.getTime())
}
Date.prototype.addSeconds=function(num){
	this.setSeconds(this.getSeconds()+num);return this;
}
Date.prototype.addMinutes=function(num){
	this.setMinutes(this.getMinutes()+num);return this;
}
Date.prototype.addHours=function(num){
	this.setHours(this.getHours()+num);return this;
}
Date.prototype.addWeeks=function(num){
	return this.addDays(num*7);
}
Date.prototype.addDays=function(num){
	this.setDate(this.getDate()+num);return this;
}
Date.prototype.addMonths=function(num){
	var m,y;
	m=this.getMonth()+num;
	y=this.getFullYear();
	while(m<0){m+=12;y--;}
	this.setYear(y);
	this.setMonth(m);
	return this;
}
Date.prototype.addYears=function(num){
	this.setFullYear(this.getFullYear()+num);return this;
}
Date.prototype.format=function(o){
	var y=this.getFullYear();
	var M=this.getMonth()+1;
	var mn=this.getMonthName();
	var d=this.getDate();
	var H=this.getHours();
	var h=(H>12)?H-12:H;if(h==0){h=12;}
	var m=this.getMinutes();
	var s=this.getSeconds();
	var t=(H>11)?"PM":"AM";

	return o.replace(/(yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|hh|h|HH|H|mm|m|ss|s|tt|t)/g,
		function($1){
			switch($1){
				case 'yyyy': return y;
				case 'yy':   return y.toString().substr(2,2);
				case 'MMMM': return mn;
				case 'MMM':  return mn.substring(0,3);
				case 'MM':   return M.pad(2,0);
				case 'M':    return M;
				case 'dddd': return this.getDayOfWeek();
				case 'ddd':  return this.getDayOfWeek(true);
				case 'dd':   return d.pad(2,0);
				case 'd':    return d;
				case 'hh':   return h.pad(2,0);
				case 'h':    return h;
				case 'HH':   return H.pad(2,0);
				case 'H':    return H;
				case 'mm':   return m.pad(2,0);
				case 'm':    return m;
				case 'ss':   return s.pad(2,0);
				case 's':    return s;
				case 'tt':   return t;
				case 't':    return t.substring(0,1);
			}
		}
	);
}

if(!window.$){window.$=function(id){return document.getElementById(id);}}

JSON.createPackage("Spotobe.Events");
JSON.createPackage("Spotobe.Locations");

Spotobe.GetBase=function(url){
	if(Spotobe.Base==null){
		var scripts=document.getElementsByTagName("script");
		for(var i=0;i<scripts.length;i++){
			var src=scripts[i].src;
			var at=src.toLowerCase().indexOf("/spotobe.js");
			if(at>-1){
				Spotobe.Base=src.substring(0,src.indexOf("/api/"));
			}
		}
	}
	return Spotobe.Base;
}
Spotobe.GetBase();

Spotobe.ToSearch=function(p){
	if(!p){return null;}
	var o="";
	if(typeof(p)=="object"){
		for(var a in p){
			if(typeof(p[a])!="function"){
				o+=a+":"+Spotobe.ToSearchValue(p[a])+";";
			}
		}
	}else{
		if(!(p+"").contains(":")){
			o="searchtext:"+p+";";
		}
	}
	if(o==""){o=p;}
	return o;
}

Spotobe.ToSearchValue=function(val){
	if(val==null){return "";}
	if(typeof(val)=="date"){
		return val.format("M/d/yyyy h:mm TT");
	}
	if(typeof(val)=="object"&&val.length){
		var o="";
		for(var i=0;i<val.length;i++){
			if(o!=""){o+=",";}
			o+=val;
		}
		return o;
	}
	return val;
}

Spotobe.Endpoint=function(name){return Spotobe.Base+"/services/"+name+".asmx";}

Spotobe.Events.WriteFeed=function(p,id,title,style){
	if(!style){style="";}else{style="-"+style;}
	if(!title){title="&nbsp;";}
	JSON.addElement(JSON.getHead(),"link",{href:Spotobe.Base+"/assets/styles/widget.css",type:"text/css",rel:"stylesheet"});
	Spotobe.Events.Find(p,function(o){
		var w=JSON.addElement($(id),"div",{id:"spotobe-widget","class":"spotobe-widget"+style});
		w=JSON.addElement(w,"div",{id:"spotobe-widget-wrap"});
		var a=JSON.addElement(w,"a",{href:Spotobe.Base,target:"_blank"});
		JSON.addElement(a,"img",{src:Spotobe.Base+"/assets/images/widget/logo.png",title:"Spotobe"});
		JSON.addElement(w,"div",{id:"spotobe-widget-header"},title);
		var ol=JSON.addElement(w,"ol",{id:"spotobe-widget-list","class":"vcalendar"});
		Spotobe.Events.ToMicroformat(ol,o.Results)
		JSON.addElement(w,"div",{id:"spotobe-widget-footer"},"Powered by <a href=\"http://www.spotobe.com/\">Spotobe</a>");
	});
}

Spotobe.Events.Find=function(p,cb){
	var p={search:Spotobe.ToSearch(p)};
	JSON.invoke(Spotobe.Endpoint("Events"),"Find",p,cb);
}

Spotobe.Events.Get=function(id,cb){
	JSON.invoke(Spotobe.Endpoint("Events"),"Retrieve",{ID:id},cb);
}

Spotobe.Events.GetCategories=function(cb){
	JSON.invoke(Spotobe.Endpoint("Events"),"GetCategories",null,cb);
}

Spotobe.Locations.Find=function(p,cb){
	JSON.invoke(Spotobe.Endpoint("Locations"),"Find",p,cb);
}

Spotobe.Locations.Get=function(id,cb){
	JSON.invoke(Spotobe.Endpoint("Locations"),"Retrieve",{ID:id},cb);
}

Spotobe.Locations.GetCategories=function(cb){
	JSON.invoke(Spotobe.Endpoint("Locations"),"GetCategories",null,cb);
}

Spotobe.Events.ToMicroformat=function(parent,o,tag,cls){
	if(typeof(parent)=="string"){parent=$(parent);}
	if(o.length){
		var cls="odd";
		for(var i=0;i<o.length;i++){
			Spotobe.Events.ToMicroformat(parent,o[i],tag,cls);
			cls=(cls=="odd")?"even":"odd";
		}return;
	}
	if(!cls){cls="";}else{cls=" "+cls;}
	if(!tag){tag="li";}
	var li=JSON.addElement(parent,tag,{"class":"vevent"+cls});
	var h3=JSON.addElement(li,"h3",{"class":"summary"});
	var a=JSON.addElement(h3,"a",{"class":"url",target:"_blank",href:Spotobe.Base+"/events/Details.aspx?ID="+o.EventID},o.Title);
	if(o.StartsOn){
		var h4=JSON.addElement(li,"h4");
		JSON.addElement(h4,"abbr",{"class":"dtstart",title:o.StartsOn.format("yyyy-MM-ddTHH:mm:ss")},o.StartsOn.format("MMMM d, yyyy h:mm tt"));
		if(o.StartsOn.toString()!=o.EndsOn.toString()){
			JSON.addElement(h4,null,null,"-");
			JSON.addElement(h4,"abbr",{"class":"dtend",title:o.EndsOn.format("yyyy-MM-ddTHH:mm:ss")},o.EndsOn.format("h:mm tt"));
		}
	}
	if(o.Location){
		Spotobe.Locations.ToMicroformat(li,o.Location);
	}	
	if(o.Description){JSON.addElement(li,"p",{"class":"description"},o.Description);}
}

Spotobe.Locations.ToMicroformat=function(parent,o,tag,options){
	if(!options){options={address:true,phone:true,geo:true};}
	if(typeof(parent)=="string"){parent=$(parent);}
	if(o.length){for(var i=0;i<o.length;i++){Spotobe.Locations.ToMicroformat(parent,o[i]);}}
	if(!tag){tag="address";}
	var adr=JSON.addElement(parent,tag,{"class":"adr"});
	var em=JSON.addElement(adr,"em",{"class":"organization-name"});
	var a=JSON.addElement(em,"a",{target:"_blank",href:Spotobe.Base+"/locations/Details.aspx?ID="+o.ID},o.LocationName);

	if(options.address&&(o.Address1||o.City||o.State)){
		if(o.Address1){JSON.addElement(adr,"span",{"class":"street-address"},o.Address1);}
		if(o.Address2){JSON.addElement(adr,"span",{"class":"extended-address"},o.Address2);}
		if(o.City||o.State){
			var line2=JSON.addElement(adr,"span",{"class":"city-state"});
			JSON.addElement(line2,"span",{"class":"locality"},o.City);
			JSON.addElement(line2,"span",{"class":"comma"},", ");
			JSON.addElement(line2,"span",{"class":"region"},o.State);
			JSON.addElement(line2,"span",{"class":"postal-code"},o.PostalCode);
		}
	}
	if(options.phone&&o.Phone){JSON.addElement(adr,"span",{"class":"tel phone"},o.Phone);}
	if(options.phone&&o.Fax){JSON.addElement(adr,"span",{"class":"tel fax"},o.Fax);}
	if(options.geo&&o.Longitude!=0&&o.Latitude!=0){
		var geo=JSON.addElement(adr,"span",{"class":"geo"});
		JSON.addElement(geo,"span",{"class":"latitude"},o.Latitude);
		JSON.addElement(geo,"span",{"class":"longitude"},o.Longitude);
	}
}