var TagCloud = Class.create();

TagCloud.prototype = {
	
	initialize: function(target, map){ 
	
		this.map = map; //TODO: replace map with event listener
		this.div = $(target);
		this.tags = new $H();
		var showAllLink = $("tags_showall");
		
		$("tags_search").observe("click", function(e){
			var tagSearch = window.prompt("Type in the tag you are looking for:");
			this.selectedTag = tagSearch;
			this.dispatch("onSelect", true);
			Event.stop(e);
		}.bind(this));
		
		showAllLink.observe("click", function(e){
			this.showAll(true);
			this.selectedTag = null;
			this.dispatch("onSelect", true);
			Event.stop(e);
		}.bind(this));
	},
	
	reset: function() {
		this.tags = new $H();
	},
	
	tagIsValid: function(tag){
		return tag.length > 0 && tag.length < 20 && !tag.match(/.*:.*=/) && !tag.match(/geo(lat|long|lng|lon)/) && !tag.match(/tagged|plazes/) && !tag.match(/cell(ac|mc|mnc|cell|net)/) && !tag.match(/zip\d/) &&!(tag.match(/bt\d/)) && tag != "map";
	},
	
	addTag: function(tagNames, object) {
		tagNames.split(" ").each(function(tag) {
			tag = unescape(tag).toLowerCase();
			if (this.tagIsValid(tag)){
				if ((typeof this.tags[tag]) != "object" ) {
					this.tags[tag] = [];
				}
				this.tags[tag].push(object);
			}
		}.bind(this));
	},
	
	showSingle: function(tag) {
		
		this.showAll(false);
		tag.value.each(
			function(o) {
				Element.show(o.image);				
			}
		);	
	},
	
	showAll: function(bool){
		
		var oldTag = this.selectedTag;
		
		this.select(null);

		if (oldTag && bool) {
			 this.selectedTag = oldTag;
		}
		
		if (bool && !this.selectedTag) {
			$("tags_showall").hide();
		} else {
			$("tags_showall").show();
		}

		if (this.map.imageList) {
			this.map.imageList.each(function(l) {
				bool ? l.show() : l.hide();
			}); 
		}
	},
	
	select: function(tagname){
		
		this.selectedTag = tagname;
		
		$A(this.div.childNodes).each(function(a){
			if (a.nodeType == 1){
				if (tagname != a.innerHTML) {
					a.removeClassName("active");
				} else {
					a.addClassName("active");
				}
			}
		});
	},
	
	render: function(){
		
		try {
		
			this.div.update("");
		
			var t= new Date();
		
			this.tags = this.tags.sortBy(function(tag){
				return -tag.value.length;
			});
		
			var subset = this.tags.slice(0, 30);
			
			var max = subset[0][1].length;
			var min = subset.last()[1].length;
			
			var scale = (max - min) / 5;
			
			var alpha = subset.sortBy(function(tag){
				return tag.key;
			});	
			
			alpha.each(function(tag){
	
				var size = Math.ceil((tag.value.length - min) / scale);
	
				var a = Element.create("a", { 
					href: "#tag:"+ tag.key, 
					innerHTML: tag.key , 
					title: tag.value.length + " stories",
					className: "mtag" + size
				});
				
				Event.observe(a, "mouseover", function(e){
					tag.value.each(function(t) {
						t.marker.highlight(true);
					});
				});
	
				Event.observe(a, "mouseout", function(e){
					tag.value.each(function(t) {
						t.marker.highlight(false);
					});
				});
				
				Event.observe(a, "click", function(e){
					
					Event.stop(e);
					this.showSingle(tag);
					this.select(a.innerHTML);
					a.blur();
					this.dispatch("onSelect", false);
				}.bind(this));			
				
				this.div.appendChild(a);
				this.div.appendChild(document.createTextNode(" "));
				
			}.bind(this));	
			
		} catch (e){
			Logger.error(e);
		}
		
		this.showAll(true);
	},
	
	dispatch: function(eventName, value) {
		
		if (this.listeners) {
			var l = this.listeners.findAll(function(o) {
				return o.eventName == eventName;
			});
			
			l.each(function(l) {
				l.callback(value);
			});
		}
	},
	
	addListener: function(eventName, callback){
		
		if(!this.listeners) {
			this.listeners = [];
		}
		
		this.listeners.push({eventName:eventName, callback:callback});
	}	
};

