	
	tpatpc.attachOnload = function(callback){ 
		if(typeof window.addEventListener!="undefined"){
			window.addEventListener("load",callback,false);
			return true;
			
		}else if(typeof document.addEventListener!="undefined"){ 
			document.addEventListener("load",callback,false);
			return true;
			
		}else if(typeof window.attachEvent!="undefined"){
			return window.attachEvent("onload",callback);
			
		}else{
			return false;
		}
	}
	
	var profilesAccordion = null;
	var menuAccordion = null;

////////Formatters
	
	var considerLocal = ["http://"+document.location.host,
						"https://"+document.location.host,
						"http://www.blogger.com",
						"http://www.tpatpc.it",
						"https://www.blogger.com"];
	var mapsLink = /^https?:\/\/maps\.google\.(co\.)?[A-Za-z]+\//i;
	var wikiLinks = /^https?:\/\/[A-Za-z]+\.wikipedia\.org\//i;
	var	youtubeLinks = /^https?:\/\/[A-Za-z]+\.youtube\.com\/watch/i;
	var friendfeedProfile = /^http:\/\/(www\.)?friendfeed.com\/\w+/i;
	
	function markExternalLinks(from) {
		if (!from) {
			from = document;
		}

		var linkz = from.getElementsByTagName("a");
		for (var i = 0; i < linkz.length; i++) { 
			if (linkz[i].href.indexOf("http:") == 0 || linkz[i].href.indexOf("https:") == 0) {
				var isExternal = true;
				for(var l=0; l<considerLocal.length && isExternal; l++) {
					if (linkz[i].href.indexOf(considerLocal[l]) == 0) {
						isExternal = false;
					}
				}
				if (isExternal) {
					if (linkz[i].getElementsByTagName("img").length <= 0 && linkz[i].innerHTML.length > 0) {
						assignExternalClass(linkz[i]);		
					}
				}	
			}
		}
	}
	
	var youtubeTemplate = null;
	
	function assignExternalClass(linkObj) {
		if (wikiLinks.test(linkObj.href)) {
			linkObj.style.background = "url(http://www.tpatpc.it/rwblog/images/links/wikipedia.png) no-repeat center right";
			linkObj.style.paddingRight = "25px";
		
		} else if (mapsLink.test(linkObj.href)) {
			linkObj.style.background = "url(http://www.tpatpc.it/rwblog/images/links/map.gif) no-repeat center right";
			linkObj.style.paddingRight = "25px";
		
		} else if (friendfeedProfile.test(linkObj.href)) {
			//do nothing but at least avoid the external link on friendfeed profile's links
			//TODO add an icon?
		
		} else if (youtubeLinks.test(linkObj.href)) {
			if (!youtubeTemplate) {
				youtubeTemplate = new Patroon.Template('youtubePlay');
			}
			var ymovie = youtubeTemplate.expand({videos:[{path:linkObj.href}]});
			linkObj.parentNode.insertBefore(ymovie,linkObj.nextSibling);
			
		
		} else {
			linkObj.style.background = "url(http://www.tpatpc.it/rwblog/images/links/external.gif) no-repeat center right";
			linkObj.style.paddingRight = "14px";
		}
	}
			
	
	function fixFlashDim(maxFlashWidth,node) {
		if (!node) {
			node = document;
		}
		var objects = node.getElementsByTagName("object");
		fixFlashDimHelper(objects,maxFlashWidth);
		var embeds = node.getElementsByTagName("embed");
		fixFlashDimHelper(embeds,maxFlashWidth);
	}
	
	function fixFlashDimHelper(objectsArray,maxFlashWidth) {	
		if (!objectsArray) return;
		for (var i=0; i<objectsArray.length; i++) {
			if (objectsArray[i].width > maxFlashWidth) {
				var newH = (maxFlashWidth*objectsArray[i].height)/objectsArray[i].width
				objectsArray[i].width = maxFlashWidth;
				objectsArray[i].height = newH;
			}
		}
	}
	
	function trim(str) {
  		return str.replace(/^\s*([\s\S]*?)\s*$/,"$1");
	}
	
///////////////////////show/hide helpers
				
	function show(id) {
		var el = document.getElementById(id);
		if (el) {
			el.style.display = "";
			return el;
		}
		return null;
	}
			
	function hide(id) {
		var el = document.getElementById(id);
		if (el) {
			el.style.display = "none";
			return el;
		}
		return el;
	}
	
	function showHideElement(element) {
		if (element.style.display != "none") {
			element.style.display = "none";
		} else {
			element.style.display = "";
		}
	}
			
///////////////////////menu helpers
	function createMenuAccordion() {
		var buttons = [
			document.getElementById("PostSet_menu_button"),
			document.getElementById("about_menu_button"),
			document.getElementById("friends_menu_button"),
			document.getElementById("credits_menu_button")
		];
		var contents = [
			document.getElementById("PostSet"),
			document.getElementById("about_panel"),
			document.getElementById("friends_panel"),
			document.getElementById("credits_panel")
		]; 
		var names = [
			"posts",
			"about",
			"friends",
			"credits"
		];
		
		try {
			menuAccordion = new tpatpc.Accordion(buttons,contents,{opened:0,openClass:"opened_menu"});
		} catch(e) {
			error("menuAccordion", e);
			return;
		}
		menuAccordion.onOpen = function(index) {
			if (window.pageTracker) {
				pageTracker._trackEvent("menuAccordion", "open", names[index]);
			}
		};
		menuAccordion.onClose = function(index) { 
			if (window.pageTracker) {
				pageTracker._trackEvent("menuAccordion", "close", names[index]);
			}
		};
		menuAccordion.onClickOpen = function(index) {
			if (index != 1) {
				profilesAccordion.collapse();
				updateHash("#"+names[index]);
				
			} else if (profilesAccordion.isCollapsed()) {
				profilesAccordion.open(0);
			}
		}
		menuAccordion.onClickClose = function(index) {
			//never show an empty page, if the accordion is closed, auto open the posts section 
			this.open(index);
			if (index == 1) {
				//if we're looking at profiles, a click on about us take us back to the bloggersList
				profilesAccordion.open(0);
			} 
			
			if (window.pageTracker) {
				pageTracker._trackEvent("menuAccordion", "auto-open", names[index]);
			}
		}
	}
			
			
///////////////////////profile helpers
	function createProfiles() {
		try {
			//create the template
			var tpatpcoTemplate = new Patroon.Template('tpatpcoTemplate');
			//expand the template with bloggers' data
			var profiles = tpatpcoTemplate.expand({tpatpcs:bloggersList});
			//return the DOM piece generated
			return profiles;
		} catch(e) {
			error("menuAccordion", e);
			return null;
		}
	}
	
	function createProfileMenu() {
		var profiles = createProfiles();
		if (!profiles) {
			return;
		}
		
		var accordionContainer = document.getElementById("about_panel");
		if (!accordionContainer) {
			error("menuAccordion", "about_panel not found");
			return;
		}
		accordionContainer.appendChild(profiles);
		
		var profileButtons = document.getElementById("profiles_buttons");
		if (!profileButtons) {
			error("createProfileMenu","profiles_buttons not found");
			return;
		}
		
		var buttons = [];
		var contents = [];
		
		//the first content is the list of bloggers and has no default button
		buttons.push(null);
		contents.push(profileButtons);
		
		//other elements are the profiles
		for (var i=0; i < bloggersList.length; i++) {
			buttons.push(document.getElementById(bloggersList[i].id+"_button"));
			contents.push(document.getElementById(bloggersList[i].id+"_content"));
		}
		
		try {
			profilesAccordion = new tpatpc.Accordion(buttons,contents);
		} catch(e) {
			error("profilesAccordion", e);
			return;
		}
		
		
		profilesAccordion.onClickOpen = function(index) {
			//its container must be visible for this accordion to work
			menuAccordion.open(1);
			
			//we must consider that the element 0 is not a blogger but is the bloggers list
			index--;
			if (bloggersList[index]) {
				updateHash("#"+bloggersList[index].id);
				loadFFUserFeed(bloggersList[index].id);
				if (window.pageTracker) {
					pageTracker._trackEvent("profileAccordion", "click_open", bloggersList[index].id);
				}
			} else {
				updateHash("#bloggers");
				if (window.pageTracker) {
					pageTracker._trackEvent("profileAccordion", "click_open", "LIST");
				}
			}
		};
				
	}

/////////////////////////navigation
	
	function showNextBlogger(index) {
		//TODO
	}
	
	function showPrevBlogger(index) {
		//TODO
	}
	
	function goBack() {
		history.back();
		goToHash();
	}
	
	function showBloggersList() {
		if (!profilesAccordion || !menuAccordion) {
			return;
		}
		
		//open bloggers list
		
		profilesAccordion.open(0);
		menuAccordion.open(1);
		
	}
	
	function showBlogger(index) {
		if (!profilesAccordion || !menuAccordion) {
			return;
		}
		
		//open the blogger [+1 because the 0 element in the list is the bloggers list
		profilesAccordion.open(index+1);
	}


/////////////////hash handling 

	var lastHash = "#posts";
	function goToHash() {
		if (!profilesAccordion || !menuAccordion) {
			return;
		}
		
		var newHash = !window.location.hash ? "#posts" : window.location.hash;
		if (lastHash == newHash) {
			return;
		}
		lastHash = newHash;
		
		if(lastHash == "#posts") {
			menuAccordion.open(0);
			
		} else if(lastHash == "#friends") {
			menuAccordion.open(2);
			
		} else if(lastHash == "#credits") {
			menuAccordion.open(3);
			
		} else if(lastHash == "#bloggers") {
			//open the bloggers list
			//menuAccordion.open(1);
			showBloggersList();
			
		} else {
			for (var id in bloggers) {
				if(lastHash == "#"+id) {
					//open the profile
					showBlogger(bloggers[id].index)
					
					break;
				}
			}
		} 
	}
	
	function updateHash(_value) {
		lastHash = _value;
		nowHash = !window.location.hash ? "#posts" : window.location.hash;
		if (_value != nowHash) {
			window.location.hash = _value;
		}
	}
	
////////////////////////songbird 

	var tpatpcBands = {
		brainless: true,
		raef: true,
		torment: true,
		thunderbreath: true,
		motherfucker: true
	};
	var yeah = false;

	function tpatpcBandDetector() {
		if (window.songbird) {
			//the user's using songbird, we can check
			
			//songbird.mainLibrary
			
			document.addEventListener("trackchange", isTpatpcArtist, false);
			
			isTpatpcArtist();
		}
	}
	
	function isTpatpcArtist(evt) {
		if (tpatpcBands[songbird.currentArtist.toLowerCase()] && !yeah) {
			yeah = true;
			alert("YEAH!");
		} 
	}	
	
////////////////////////more	
			
	var waitingErrors = [];
	function error(desc,detail,nowOrNerver) {
		if (window.pageTracker) {
			if (detail.message) {
				detail = detail.message;
			} else if (detail.getMessage) {
				detail = detail.getMessage();
			}
			pageTracker._trackEvent("errors", desc, detail);
		} else if(!nowOrNerver) {
			waitingErrors.push({desc:desc,detail:detail});
		}
	}
			
	function dequeueErrors() {
		for (var i=0; i<waitingErrors.length; i++) {
			error(waitingErrors[i].desc,waitingErrors[i].detail,true);
		}
	}

////////////////////////init blog!
	
	function initBlog() {
		createMenuAccordion();
		createProfileMenu();
		
		show("menu_ul");
		
		markExternalLinks(document.getElementById("PostSet"));
		fixFlashDim(480);
		
		tpatpcBandDetector();
		
		setInterval(goToHash,500);
	}
	
	var loadPostCommentsQueue = [];
	
	function queueToLoad(url,id) {
		loadPostCommentsQueue.push({url:url,id:id});
	}
	
	function onLoadOperation() {
		for (var i=0; i<loadPostCommentsQueue.length; i++) {
			loadFFPostComments(loadPostCommentsQueue[i].url,loadPostCommentsQueue[i].id);
		}
	}
	
	tpatpc.attachOnload(onLoadOperation);
	
	
	

	