TIMEOUT = 1000; //in milli seconds
API_KEY = "7a48a17c22a86b28bfbe20314633f0f0";
RELATED_TAGS_API_ENDPOINT = "http://api.flickr.com/services/rest/?method=flickr.tags.getRelated&api_key=" + API_KEY + "&format=json&jsoncallback=?&tag=";
SEARCH_API_ENDPOINT = "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + API_KEY + "&tag_mode=all&per_page=160&extras=tags,url_sq,url_m,url_o&sort=interestingness-desc&format=json&jsoncallback=?&tags=";

relatedTags = new Array();

// Define console to avoid errors when Firebug isn't available
// Code from Ryan
if(!window.console){ window.console = {log:function(){}}; }

//Use YQL to fetch an intersection of related tags.... thanks to Jeremy Hubert.
function populateTagsFromYql(activeTags) {
	//Clear existing tags
	relatedTags = new Array();

	yqlUri = "http://query.yahooapis.com/v1/public/yql?q=use%20'http%3A%2F%2Fcode.thejo.in%2Fischool%2Fiolab%2Fflickrtagr%2Fflickr_related_tags.xml'%20as%20flickrTags%3B%20select%20*%20from%20flickrTags%20where%20tag%20in%20('" + activeTags.join("'%2C'")  + "')%3B&format=json&diagnostics=false&debug=true&callback=?";

	$.getJSON(yqlUri, function (data) {
		relatedTags = data.query.results.tag;
		populateYqlTags(relatedTags, activeTags.length);
	});
}

//Performs the actual action of appending the tags
function populateYqlTags(tagList, activeTagNum) {
	for(var i in tagList) {
		//Why 22? That many fit without overflowing...
		if(i > (22 - parseInt(activeTagNum))) {break;}
		$("#related-tags").append("<li><a class='tag' href=''>" + tagList[i] + "</a></li");
	}

	$('img#loader').hide();
}

//NOT USED
//Accepts an array of tags and populates the viewer div elments with the results of a 
//search for those tags on Flickr
function populatePhotos(tagList) {
	
	$("#viewer").find('a').remove();
	
	
	if(tagList.length != 0){
		$('img#picture-loader').show();
		$('#image-count').empty();
		$.getJSON(SEARCH_API_ENDPOINT + tagList.join(","), function (data) {
			photoDetails = {};
			photoDetails.total = data.photos.total;
			
			var cnt = 0;
			photoDetails.photo = {};
			$.each(data.photos.photo, function(j, photo) {
				photoDetails.photo[cnt] = {"url_sq" : photo.url_sq, 
										   "url_m" : photo.url_m,
										   "url_o" : photo.url_o,
										   "tags" : photo.tags,
										   "title" : photo.title};
				cnt++;
			});
			console.log(photoDetails);

			$('img#picture-loader').hide();
		
			
			for(var i in photoDetails.photo) {
				if (photoDetails.photo[i].url_m != undefined) {
					$("#viewer").append('<a class="photo" href="' + photoDetails.photo[i].url_m + '" target="_blank"><img src="' + photoDetails.photo[i].url_sq + '" alt="' + photoDetails.photo[i].title + '" rel="' + photoDetails.photo[i].tags + '" /></a>');
				} else if(photoDetails.photo[i].url_o != undefined) {
					$("#viewer").append('<a class="photo" href="' + photoDetails.photo[i].url_o + '" target="_blank"><img src="' + photoDetails.photo[i].url_sq + '" alt="' + photoDetails.photo[i].title + '" rel="' + photoDetails.photo[i].tags + '" /></a>');
				}
			}
			
			//show image count
			$('#image-count').append(number_format(photoDetails.total, 0, '.', ','));			
			
		});
	
	}
	
	
}

//NOT USED
//Pass an array of tags to populate the related-tags div element with an 
//intersection of the related tags (for each tag passed to the function)
function populateRelatedTags(tagList) {
	//Clear existing tags
	relatedTags = new Array();
	
	var tagCount = 0;
	
	$('img#loader').show();
	for(var i in tagList) {
		
		$.getJSON(RELATED_TAGS_API_ENDPOINT + tagList[i], function (data) {
			var tagArray = new Array();
			var cnt = 0;
			$.each(data.tags.tag, function(j, tag) {
				tagArray[cnt] = tag._content;
				cnt++;
			});
			
			relatedTags[tagCount] = tagArray;
			tagCount++;
		});
		
	}
	//console.log("Unique tags - " + relatedTags);
	//Sleep for 500 ms per tag to let all the asynchronous calls complete
	setTimeout('populateTags()', tagList.length * TIMEOUT);
}

//Performs the actual action of appending the tags
function populateTags(tagList) {
	var tagIntersection = intersect(relatedTags);
	
	for(var i in tagIntersection) {
		if(i > 20) {break;}
		$("#related-tags").append("<li><a class='tag' href=''>" + tagIntersection[i] + "</a></li");
	}
	
	$('img#loader').hide();
}

//Find the intersection of a given set of arrays
//Argument is a multi-dimensional array
function intersect(arrays) {
	var elems = {};
	var result = new Array();
	
	for(var i in arrays) {
		subArray = arrays[i];
		for (var j in subArray) {
			if(! elems[subArray[j]] ) {
				elems[subArray[j]] = 1;
			} else {
				elems[subArray[j]] = elems[subArray[j]] + 1;
			}
		}
	}
	
	var cnt = 0;
	for (var k in elems) {
		if(elems[k] == arrays.length) {
			result[cnt] = k;
			cnt++;
		}
	}
	//console.log("Result - " + result);
	return result;
}


/* UI Scripting */
var activeTags = Array();

//actually submits the tag entered in the search field
function submitSearch(newTag){

		$('#lightbox').fadeOut();		//removes lightbox if it's currently visible

		//if text field is empty, don't do anything
		if (newTag == "" || newTag == " "){
			false;
		}
		else {
			
			//an undefined tag only happens when you click the remove "x"
			if(newTag != undefined){
				
				//if the array already contains the tag, show an alert
				if ($.inArray(newTag, activeTags) != -1){
					alert("You've already added \"" + newTag + "\".");
					$('input#search-box').attr('value', '');
				}
				else {
					activeTags.push(newTag);
					$('ul#active-tags').append("<li><span>" + newTag + "</span><a class='remove-tag' href='#'>x</a></li>");
					$('input#search-box').attr('value', '');
			
				}
			}
				//shows the related tags header (only needed if hidden)
				$('div#related-tags-title').show();
				$('ul#related-tags').show();
								
				//Clear existing list of tags
				$("#related-tags").empty();
				
				//populates the related tags
				//populateRelatedTags(activeTags);	
				populateTagsFromYql(activeTags);
				
				//populate photos
				populatePhotos(activeTags);
					
		}
}

$(document).ready(function() {
	
	//hide related tags header initially
	$('div#related-tags-title').hide();
	$('ul#related-tags').hide();
	$('img#loader').hide();
	$('img#picture-loader').hide();
	$('#lightbox').hide();
	
	//when you click on a photo
	$('a.photo').live('click', function() {
		
		var photoURL = $(this).attr('href');

		$('#lightbox').fadeIn();
		$('#lightbox').append("<img class='big-photo' src='" + photoURL  + "'/>" );
		
		$('#lightbox').click(function() {

			$(this).fadeOut();
			$('img.big-photo').remove();
			
		})
		
		return false;
		
	});
	
	//clicking on a related tag adds it to the active tags
	$('a.tag').live('click', function() {
		
		var clickedTag = $(this).text();
		
		submitSearch(clickedTag);
		return false;		
	});
	
	
	
	//hitting enter from the search field
	$('input#search-box').keyup(function(e) {
			
			if(e.keyCode == 13){
				submitSearch($('input#search-box').attr('value'));
			}
	});

	//click on the search/add button
	$('a#search-button').click(function() {
		
		submitSearch($('input#search-box').attr('value'));
		
	});
	
	
	//click on the "x" in the active tags section
	$('a.remove-tag').live("click", function() {
		
		var deletedTag = $(this).parent().find('span').text();
		console.log(deletedTag);
		
		//remove tag from array of active tags
		activeTags = jQuery.grep(activeTags, function(value) {
			return value != deletedTag;
		});
		
		//remove tag from ui
		$(this).parent().remove();

		//submits search for new set of tags
		submitSearch();
		
		if (activeTags.length == 0){
			$('div#related-tags-title').hide();
			$('ul#related-tags').hide();
		}
		
	});
	
});

/* Made by Mathias Bynens <http://mathiasbynens.be/> */
function number_format(a, b, c, d) {
 a = Math.round(a * Math.pow(10, b)) / Math.pow(10, b);
 e = a + '';
 f = e.split('.');
 if (!f[0]) {
  f[0] = '0';
 }
 if (!f[1]) {
  f[1] = '';
 }
 if (f[1].length < b) {
  g = f[1];
  for (i=f[1].length + 1; i <= b; i++) {
   g += '0';
  }
  f[1] = g;
 }
 if(d != '' && f[0].length > 3) {
  h = f[0];
  f[0] = '';
  for(j = 3; j < h.length; j+=3) {
   i = h.slice(h.length - j, h.length - j + 3);
   f[0] = d + i +  f[0] + '';
  }
  j = h.substr(0, (h.length % 3 == 0) ? 3 : (h.length % 3));
  f[0] = j + f[0];
 }
 c = (b <= 0) ? '' : c;
 return f[0] + c + f[1];
}
