if (typeof(Cluztr_Engagd)=='undefined') Cluztr_Engagd = {};
if (typeof(Cluztr_Engagd.APML_tagcloud)=='undefined') {

    Cluztr_Engagd.APML_tagcloud = function() {
	        return {
            DEBUG: false,
			static_url_root: 'http://www.cluztr.com/api/',
			proxy_url: 'http://www.cluztr.com/proxy.php?proxy_url=',
			json_url: 'http://www.cluztr.com/feeds/json/',
			apml_profiler_url: encodeURIComponent('https://profiler.engagd.com/user/edW5tBslm1reeMibzOFunTqsP5aIJ6/apml?url=' + encodeURIComponent(location.href)),
			apml_url:(typeof(apml_url) == "undefined" || apml_url == null || apml_url == "" ? false : apml_url),
			apml_json_url:(this.apml_url == false ? this.apml_profiler_url : this.apml_url),
			default_class: "tagcloud_container",
			limit: (typeof(limit) == "undefined" ? 10 : limit),
			tagcloud_title: (tagcloud_title == null || tagcloud_title == "" ? false : tagcloud_title),
			number_font_classes: 11,

            did_init:        false,
			did_onload:        false,

            badges:          {},

            init: function() {
                this.badges = {};

              	this.insertBadgeCSS();
               	this.addLoadEvent(this.onload);
				this.did_init = true;
            },

            onload: function() {
				if(this.did_onload == true) return;
				this.did_onload = true;

				this.fetchBadgeJSON();
            },

            insertBadgeCSS: function() {
			// add a CSS to the document
                var bcss = document.getElementById('cluztr-APML_tagcloud-css');
                if (!bcss) {
                    bcss = this.el('link', {
                        'id':   'cluztr-APML_tagcloud-css',
                        'type': 'text/css',
                        'rel':  'stylesheet',
                        'href': this.static_url_root+'/css/apml_tagcloud.css'
                    }, []);
                    document.getElementsByTagName('head')[0].appendChild(bcss);
                }
                bcss = null;
            },

            register: function(divid, url, title, opts) {
                var badge = { 
                    'divid': divid, 
                    'url': url, 
                    //'hash': hex_md5(url),
                    'title':title, 
                    'opts': opts||{} 
                };
                this.badges[url] = badge;
                
				// empties badge div and adds a new element
				/*this.replaceChildNodes(
                    document.getElementById(badge.divid), 
                    this.renderPostButton(badge)
                );
				*/
            },

            writeBadge: function(divid, url, title, opts, classname) {
                if (!classname) classname = this.default_class;
                //document.writeln('<div class="'+classname+'" id="'+divid+'"></div>');
				document.writeln('' +
					'<div class="'+classname+'">' +
					(this.tagcloud_title != false ? '<div class="tag_cloud_header">' + this.tagcloud_title + '</div>' : '') +
					'<div class="tagcloud" id="' + divid + '">Loading...</div>' +
					'<div class="tag_cloud_footer">' +
					'<a href="' + this.apml_file_url() + '"><img src="http://www.cluztr.com/api/img/apml.gif" border="0" align="absmiddle" /></a>' + ' ' +
					'Built by <a href="http://www.cluztr.com/">Cluztr</a>, powered by <a href="http://www.engagd.com/">Engagd</a>.</div>' +
					'</div>' + 
					'');
                this.register(divid, url, title, opts);
            },
			
			 handler: function() {
				alert(http_request.responseText);
				/*
				if(checkReadyState(http_request)) {
					var xml_object = http_request.responseXML.documentElement;
					Cluztr_Engagd.APML_tagcloud.builder(xml_object); // hardcode object name
				}
				*/
            },

            builder: function(xml_object) {
				// process APML and build
				var profiles = xml_object.getElementsByTagName("Profile");
				var profile_main = profiles[0];
				var implicit_data = profile_main.getElementsByTagName("ImplicitData");
				var a = implicit_data[0];
				var implicit_concepts = a.getElementsByTagName("Concepts");
				var b = implicit_concepts[0];
				
				var concept_nodes = b.getElementsByTagName("Concept");
				
				var data_object = new Array();
				for(var i=0; i<concept_nodes.length; i++) {
					var node = concept_nodes[i];
					var obj = {
						'key':node.getAttribute('key'),
						'value':node.getAttribute('value'),
						'updated':node.getAttribute('updated'),
						'from':node.getAttribute('from')
					};
					data_object.push(obj);
				}
				
				var inner_html = '';
				for(var i=0; i<data_object.length; i++) {
					var key = data_object[i].key;
					
					random_num = (Math.round((Math.random()*(this.number_font_classes-1))+1))
					
					inner_html += '<a href="http://www.google.ca/" class="font_' + random_num + '">' + key + '</a> ';
					// extra empty space at end is required for wrapping to work ... wtf?
				}
				
				var badge = this.badges[location.href];
				
				document.getElementById(badge.divid).innerHTML = inner_html;
				
				//this.buildBadge(badge, data_object);
            },
			
			apml_file_url: function() {
				return (this.apml_url == false ? this.apml_profiler_url : this.apml_url);
			},
			
			fetchBadgeJSON: function() {
                var json_url = this.json_url +
                    "?callback=Cluztr_Engagd.APML_tagcloud.handleBadgeJSON" +
					"&m=apml_page" +
					"&u=" + this.apml_file_url() +
                    "&noCacheIE="+(new Date()).getTime();

                var scr = document.createElement("script");
                scr.setAttribute("type", "text/javascript");
                scr.setAttribute("src", json_url);
                scr.setAttribute("id", 'Cluztr_Engagd-APML_tagcloud-json');

                this.script_ele = scr;
                document.getElementsByTagName("head").item(0).appendChild(this.script_ele);
            },

            handleBadgeJSON: function(data) {
				var badge = this.badges[location.href];
                this.buildBadge(badge, data);

                document.getElementsByTagName("head").item(0).removeChild(this.script_ele);
                this.script_ele = null;
            },
			

            buildBadge: function(badge, data) {				
                badge.data = data;

                this.replaceChildNodes(
                    document.getElementById(badge.divid), 
                    this.renderBadge(badge)
                );
            },
			
			renderBadge: function(badge) {
                var el          = this.bind(this.el);
				var map         = this.bind(this.map);
                var data        = badge.data;

				// calculate key values
				var highestValue = null;
				var lowestValue = null;
				for(var i=0; i<data.length; i++) {
					var value = Number(data[i]['value'])*100;

					highestValue = (highestValue > value && highestValue != null? highestValue : value);
					lowestValue = (lowestValue < value && lowestValue != null? lowestValue : value);
				}				
				var eachClass = Math.round((highestValue-lowestValue)/this.number_font_classes);
				eachClass = (eachClass == 0 ? 1 : eachClass);				

				return [
					map( function(data) {
						var value = data.value*100;
						var classNumber = Math.round((value-lowestValue)/eachClass);
						classNumber = (classNumber == 0 ? 1 : classNumber);
								  
						var element = el('a', {'class':'font_'+classNumber}, null);
						element.innerHTML = data.key + ""; // workaround to get it to work on IE and FF
						// extra empty space at end is required for word spacing to work ... wtf?
						return element;
						}, data)
				]
			},
			
            // See: http://dean.edwards.name/weblog/2006/06/again/
            addLoadEvent: function(func) {
                var init = this.bind(func);

                // for Mozilla and Opera browsers
                if (document.addEventListener) {
                    document.addEventListener("DOMContentLoaded", init, false);
                }
                 
                // for WebKit browsers
                if (/WebKit/i.test(navigator.userAgent)) { // sniff
                    var _timer = setInterval(function() {
                        if (/loaded|complete/.test(document.readyState)) {
                            clearInterval(_timer);
                            init(); // call the onload handler
                        }
                    }, 10);
                }

                // for anyone else not covered above.
                var oldonload = window.onload;
                if (typeof window.onload != 'function') {
                    window.onload = init;
                } else {
                    window.onload = function() {
                        if (oldonload) { oldonload(); }
                        init();
                    }
                }
            },

            bind: function(func) {
                var obj = this;
                return function() { return func.apply(obj, arguments) };
            },

            map: function(fn, list) {
                var rv = [];
                fn = this.bind(fn);
                for (var i=0; i<list.length; i++) rv[rv.length] = fn(list[i]);
                return rv;
            },

            replaceChildNodes: function(parent, nodes) {
                while (parent.firstChild) 
                    parent.removeChild(parent.firstChild);
                return this.appendChildNodes(parent, nodes);
            },

            appendChildNodes: function(parent, nodes) {
                if (!nodes || !nodes.length) return;
                for (var i=0; i<nodes.length; i++) {
                    var node = nodes[i];
                    if (!node) continue;
					
					parent.innerHTML += " "; // extra empty space at end is required for word spacing to work ... wtf?
					
                    if (node.nodeType) 
                        parent.appendChild(node);
                    else if ( (typeof(node) == 'object') && node.length)
                        this.appendChildNodes(parent, node);
                    else
                        parent.appendChild(document.createTextNode(''+node));
                }
            },

// el('a', {'class':'xxx', 'href':'xxx', 'title':'xxx'}, [ el('span', {'class':'xxx'}, null) ])
            el: function(name, attrs, nodes) {
                var elem = document.createElement(name);
                if (attrs) for (k in attrs) {
                    var v = attrs[k];

                    if (k.substring(0, 2) == "on") {
                        if (typeof(v) == "string") {
                            v = new Function(v);
                        }
                        elem[k] = v;
                    } else {
                        elem.setAttribute(k, v);
                    }

                    switch(k) {
                        // MSIE seems to want this.
                        case 'class': elem.className = v; break;
                    }
                }
                if (nodes) this.appendChildNodes(elem, nodes);
                return elem;
            },

            EOF:null
        };
    }();
}

Cluztr_Engagd.APML_tagcloud.init();
if (!Cluztr_Engagd.APML_tagcloud_MANUAL_MODE) {
	Cluztr_Engagd.APML_tagcloud.writeBadge("Cluztr_Engagd_APML_tagcloud_"+Math.random(), location.href, document.title, {});
	//Cluztr_Engagd.SiteBadge.onload();
}


// http://www.captain.at/howto-ajax-permission-denied-xmlhttprequest.php
var http_request = false;
function loadXMLDoc( url, callback ) {	
	/*xmlhttp=null;
	// code for Mozilla, etc.
	
	if(window.XMLHttpRequest) {
		xmlhttp=new XMLHttpRequest()
	} else if (window.ActiveXObject) {
		// code for IE
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
	}
	*/
	/*
    http_request = new XMLHttpRequest();
    if (http_request.overrideMimeType) {
      http_request.overrideMimeType('text/xml');
    }
    if(!http_request) {
      alert('Cannot create XMLHTTP instance');
      return false;
    }
	*/
	var http_request = null;
	if (typeof XMLHttpRequest != 'undefined') {
	  http_request = new XMLHttpRequest();
	} else {
	  try {
		http_request = new ActiveXObject("Msxml2.XMLHTTP");
	  } catch (e) {
		http_request = new ActiveXObject("Microsoft.XMLHTTP");
	  }
	}
	
	http_request.onreadystatechange = callback;
	try{
		netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); 
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {}
    http_request.open('GET', url, true);
    http_request.send(null);
}

function checkReadyState(obj) {
	if(obj.readyState == 4) {
		if(obj.status == 200) {
		  return true;
		} else {
		  alert("Problem retrieving XML data");
		}
	}
}

function onResponse() 
{
  if(checkReadyState(http_request))
  {
  var response = xmlhttp.responseXML.documentElement;
  txt="<table border='1'>"
  x=response.getElementsByTagName("CD")
  for (i=0;i<x.length;i++)
    {
    txt=txt + "<tr>"
    xx=x[i].getElementsByTagName("TITLE")
      {
      try
        {
        txt=txt + "<td>" + xx[0].firstChild.data + "</td>"
        }
      catch (er)
        {
        txt=txt + "<td> </td>"
        }
      }
    xx=x[i].getElementsByTagName("ARTIST")
      {
      try
        {
        txt=txt + "<td>" + xx[0].firstChild.data + "</td>"
        }
      catch (er)
        {
        txt=txt + "<td> </td>"
        }
      }
    txt=txt + "</tr>"
    }
  txt=txt + "</table>"
  document.getElementById('copy').innerHTML=txt
  }
}



// mozXPath [http://km0ti0n.blunted.co.uk/mozxpath/] km0ti0n@gmail.com
// usage
// var node_value = xmlObj.selectSingleNode("/Nodes/Node" + "/text()").nodeValue;
// var attribute_value = xmlObj.selectSingleNode("//Node[@id='1']/@AttributeName").nodeValue;

// array
// var array = xmlObj.selectNodes("/Nodes/Node");
// array[i].getAttribute("id"); // <- attribute from array

if(document.implementation.hasFeature("XPath", "3.0")) {
	XMLDocument.prototype.selectNodes = function(cXPathString, xNode) {
		if( !xNode ) { xNode = this; }
		var oNSResolver = this.createNSResolver(this.documentElement)
		var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		var aResult = [];
		for( var i = 0; i < aItems.snapshotLength; i++)	{
			aResult[i] =  aItems.snapshotItem(i);
		}
		return aResult;
	}
	XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode) {
		if( !xNode ) { xNode = this; } 
		var xItems = this.selectNodes(cXPathString, xNode);
		if( xItems.length > 0 )	{
			return xItems[0];
		} else {
			return null;
		}
	}
	Element.prototype.selectNodes = function(cXPathString) {
		if(this.ownerDocument.selectNodes) {
			return this.ownerDocument.selectNodes(cXPathString, this);
		} else{throw "For XML Elements Only";}
	}
	Element.prototype.selectSingleNode = function(cXPathString) {	
		if(this.ownerDocument.selectSingleNode)	{
			return this.ownerDocument.selectSingleNode(cXPathString, this);
		} else{throw "For XML Elements Only";}
	}
}