/* Copyright (c) 2011 mezz, Inc.  All Rights Reserved
*/
var mz_url = "http://l.mezz.com/m/";
var mz_web_url = "http://www.mezz.com/";
var mz_apikey;
var mz_arrayIndex = 0;
var mz_limit;
var mz_results;
var mz_radius;
var mz_lat = 0;
var mz_lon = 0;
var mz_divid;
var mz_interval = 3000;
var mz_timeoutId = 0;
var mz_timestamp = 0;
var mz_continious = false;
var mz_delay = 0;
var mz_firstTime = true;

/* 
 * One of the entry points to populate a feed.  Does not
 * do any animation.  Use animatefeed for animation.
 */
function populatefeed(apikey, lat, lon, radius, limit, divid)
{
	getfeed("latest", apikey, lat, lon, radius, limit, divid);
}

/*
 * Internal function to get the feed.
 */
function getfeed(fdtype, apikey, lat, lon, radius, limit, divid)
{
	var args = { "auth_userid": apikey, 
			"longitude": +lon,
			"latitude": +lat,
			"limit": +limit
		};
	if (+radius > 0) args.radius = radius;

	$.get(mz_url + "v1/feed/" + fdtype, 
			args,
			function(data) {
				$.each(data.results, function(i,item)
				{
	            	$(divid).append(makeCard(item, lat, lon));
	 			});
			  },
			  "jsonp");
}

function makeFooter()
{
	return $('<div>').attr('class', 'mz_feedfooter').attr('id', 'mz_feedfooter').html(''
			+ '    <a href="http://www.mezz.com" target="_blank"><img class="mz_feedfooterlogo" src="' + mz_web_url + 'image/mezzlogowhite.png" border="0"/></a>'
			+ '    <a class="mz_feedfootermsg" href="http://www.mezz.com" target="_blank">Share your discoveries</a>'
			);
	
}
/*
 * Create the card structure.
 */
function makeCard(item, lat, lon)
{
	var heart = "like";
	if (item.card.like_count > 0) heart = "liked";
	var cardurl = mz_url + 'c?cid=' + item.card.card_id;
	
	return $('<div>').attr('class', 'mz_card').attr('id', 'mz_card').attr('onclick', 'window.open("' + cardurl + '", "_blank")').html(''
			+ '    <img class="mz_photo" src="' + item.card.image_url + '" alt="" onload="resizeImage(this);"/>'
			+ '    <div class="mz_desc">'+ item.card.text + '</div>'
			+ '    <img class="mz_clock" src="' + mz_web_url + 'image/clock.png" alt=""/>'
			+ '    <div class="mz_time">' + item.card.timeDisplay + '</div>'
			+ '    <div class="mz_by">by</div>'
			+ '    <div class="mz_auth">' + item.card.author.user_object.username + '</div>'
			+ '    <div class="mz_dist">' +  distance(lat, lon, item.card.latitude, item.card.longitude, true) + '</div>'
			+ '    <div class="mz_vsep"></div>'
			+ '    <img class="mz_heart" src="' + mz_web_url + 'image/' + heart + '.png" alt="" border="0"/>'
			+ '    <div class="mz_likecount">' + item.card.like_count + '</div>'
			);
}

/* resizeImage:  Actually this simply offsets the image to the negative margin on
 * the top or the left, and then overlays a mask.  This is only applied if the image width and height are different.
 * So square pictures do not have any changes.  Only pictures with a different width / height are "resized".
 * Note that the mask works regardless of the size - as long as it is 128 x 128 and smaller. 
 */
function resizeImage(img)
{
	// current CSS style width.
	var w = img.width;
	var newWidth;
	var newHeight;
	var half;

	// We need to create a new image temporarily to determine the actual width.
	var i2 = new Image();
	i2.src = img.src;
	
	if (i2.width == i2.height) return;
	
	w = parseInt(w);
		
	if (i2.width > i2.height) 
	{
		newWidth = parseInt(i2.width * w / i2.height);
		half = parseInt((newWidth - w) / 2);
		var rect = "rect(auto, " + (w+half) + "px, auto, " + half + "px)";
			
		$(img).css({left: -half, width: newWidth, clip: rect});
//		img.style.left = -half;
//		img.style.width = newWidth;
//		img.style.clip = "rect(auto, " + (w+half) + ", auto, " + half + ")";
	} else {
		// Height > Width
		newHeight = parseInt(i2.height * w / i2.width);
		half = parseInt((newHeight - w) / 2);
		var rect = "rect(" + half + "px, auto, " + (w+half) + "px, auto)";
		
		$(img).css({top: -half, height: newHeight, clip: rect});
//		img.style.top = -half;
//		img.style.height = newHeight;
//		img.style.clip = "rect(" + half + "px, auto," + (w+half) + "px, auto)";
	}
	
	// We need to add a mask over the image to get the rounded corners.
	// The masked image has a rounded corner, but transparent in the middle
	// It's z-index is very high so it overlays on top of the image.
	// This mask apparently works every if you resize - it will
	// simply resize the image.  So no need for another image
	// for mobile or other purposes.
	var mask = new Image();
	mask.src = mz_web_url + "image/mask128.png";
	mask.className = "mz_photo_mask";
	
	$(img).parent().append(mask);
	

}

/*
 * Entry point to load an animated feed:
 * apikey: Specify the API Key
 * lat: Latitude
 * lon: Longitude
 * radius: Radius of the data.
 * limit: # of items to load at a time.  Note that each will be still animated.
 * continious: true to rotate on a continious basis.  When all limit # items are displayed,
 *  we go back and load them again.  It is possible that newer items will be received.
 * divid: Id of the div.  Make sure to specify it leading with #
 * interval: The interval specified in milliseconds.
 */
function animatefeed(apikey, lat, lon, radius, limit, continious, divid, interval, delay)
{
	mz_apikey = apikey;
	mz_lat = +lat;  // + in front converts variable to numbers if they are strings.
	mz_lon = +lon;
	mz_radius = +radius;
	mz_limit = +limit;
	mz_divid = divid;
	mz_continious = continious;
	
	if (!varIsEmpty(interval))  {
		if (interval < 50) interval *= 1000;
		mz_interval = interval;
	}

	$(divid).append(makeFooter());

	getfeed2("latest", apikey, lat, lon, radius, limit, divid, delay);

}

/*
 * add an item from the array, and then call itself with a timeout to load more.
 */
function addItem()
{
	if (mz_arrayIndex >= mz_limit || mz_arrayIndex >= mz_results.length) {
		if (mz_continious) {
			mz_arrayIndex = 0;
			mz_firstTime = false;
			animatefeed(mz_apikey, mz_lat, mz_lon, mz_radius, mz_limit, mz_continious, mz_divid, mz_interval, mz_delay);
		}
		return;
	}
	
	$el = makeCard(mz_results[mz_arrayIndex], mz_lat, mz_lon);
	$el.attr('style', 'display:none;');
	$(mz_divid).prepend($el);
	$el.slideDown('slow');
	mz_arrayIndex++;
	
	var num = $(mz_divid).children().size();
	
	if (num > mz_limit) {
		$(mz_divid).children("div[id=mz_card]:last").remove();
	}
	
	// We add the first 10 items immediately 
	// with a 50 millisecond delay
	// instead of the normal delay requested.
	var interval = 50;
	if (!mz_firstTime || num > 10) {
		interval = mz_interval;
	}
	mz_timeoutId = setTimeout(addItem, interval);
}

/*
 * Load the feed and then call addItem to animate.
 */
function getfeed2(fdtype, apikey, lat, lon, radius, limit, divid, delay)
{
	var args = { "auth_userid": apikey, 
			"longitude": lon,
			"latitude": lat,
			"timestamp": mz_timestamp,
			"limit": limit
		};
	
	if (+radius > 0) args.radius = radius;
	
	if (!varIsEmpty(delay)) {
		mz_delay = +delay;
		args.delay = mz_delay;
	}
	
	$.get(mz_url + "v1/feed/" + fdtype, 
			args,
			function(data) {
				mz_results = data.results.reverse();
	  			addItem();
			  },
			  "jsonp");
}

// These functions are part of utils.js, but are used by SJSU directly - 
// so we have it here as well until we get them to change things to an iframe.
function Create2DArray(cols) 
{
	var arr = [];

	for (var i=0; i<cols; i++) {
		arr[i] = [];
		arr[i][0] = 0;
	}

	return arr;
}

function distance(lat1, lon1, lat2, lon2, inMiles) {
  
	  var Rk = 6371; // Radius of earth in km
	  var Rm = 3958.7558657440545; // Radius of earth in Miles 
	  var dLat = (lat2-lat1).toRad();
	  var dLon = (lon2-lon1).toRad();
	  lat1 = lat1.toRad();
	  lat2 = lat2.toRad();

	  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
	          Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
	  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
	  
	  var R = Rm;
	  var suffix = " mi";
	  
	  if (!inMiles) {
		  R = Rk;
		  suffix = " km";
	  }
	  
	  var dist = R*c;
	  
	  if (dist < 10) {
		  // one decimal digit if distance less than 10
		  // like 10.2 mi
		  return Math.round(dist*10)/10 + suffix;
	  }
	
	  // Otherwise round off the number and return.
	  return Math.round(dist) + suffix;
}    

/** Converts numeric degrees to radians */
if (typeof(Number.prototype.toRad) === "undefined") {
  Number.prototype.toRad = function() {
    return this * Math.PI / 180;
  };
}

/* getUrlVars.  Usage:
 * Get object of URL parameters
 * var allVars = $.getUrlVars();
 *
 * Getting URL var by its nam
 * var byName = $.getUrlVar('name');
*/
$.extend({
	  getUrlVars: function(){
	    var vars = [], hash;
	    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
	    for(var i = 0; i < hashes.length; i++)
	    {
	      hash = hashes[i].split('=');
	      vars.push(hash[0]);
	      vars[hash[0]] = hash[1];
	    }
	    return vars;
	  },
	  getUrlVar: function(name){
	    return $.getUrlVars()[name];
	  }
	});


/*
 * This will return true for
 * - undefined  // Because undefined == null
 * - null
 * - []
 * - ""
 * - and zero argument functions since a function's length is the number of declared parameters it takes.
 */
function varIsEmpty(value)
{
	return (typeof value === "undefined" || value === null | value.length === 0);
}

/*
 * String.format function.
 */
String.prototype.format = function() {
    var formatted = this;
    for (var i = 0; i < arguments.length; i++) {
        var regexp = new RegExp('\\{'+i+'\\}', 'gi');
        formatted = formatted.replace(regexp, arguments[i]);
    }
    return formatted;
};


