/*
 * preView code
 */
function PreView(mapDivID)
{
	/*
	 * Google Maps
	 */
    this.mapDivID = mapDivID;
    this.mapDiv = null;
    this.map = null;
    this.markerMgr = null;
	this.geoCodeCache = new GGeocodeCache();
    this.geoCoder = new GClientGeocoder(this.geoCodeCache);
    
	/*
	 * Twitter
	 */
    this.tweets = new TweetList();
    this.tweeterDetails = [];
    this.twitterURLs =  {
        'predevcamp' : 'q=predevcamp',
        'webOS' : 'q=webOS',
        'palm+pre' : 'q=palm+pre'
    };
    
    this.getTweetsTimerID = null;
    this.processTweetsTimerID = null;
    
    this.twAPI = {
        'msecsUntilReset' : 3600,
        'reqsRemaining' : 0,
		'reqLimit' : 0
    };
	
    this.currentTweet = {};
    this.tweetDiv = $('<div class="tweetDiv"><img src="/images/cornerArrow.gif" height="8" width="8" alt="" id="arrow"/>'+
					  '<div id="tweeterImg"><img src="" height="48" width="48" alt=""/></div>'+
					  '<div id="tweeterText"> </div>'+
					  '</div>');
    
	var oThis = this;
    $('document').ready(this.getSetUp(oThis));
}

/*
 * Generate the configuration function
 */
PreView.prototype.getSetUp = function()
{
    var oThis = this;
    
    return (function()
    {
		oThis.mapDiv = $('div#'+this.mapDivID);
		oThis.map = new GMap2(document.getElementById('preViewMap'));
		oThis.map.addControl(new GSmallZoomControl());
		oThis.map.setCenter(new GLatLng(50, 0), 3);
		oThis.map.addMapType(G_PHYSICAL_MAP);
		oThis.map.setMapType(G_PHYSICAL_MAP);
		
		oThis.markerMgr = new MarkerManager(oThis.map);
		
		$.getJSON('http://predevcamp.org/cgi-bin/getCityInfo.pl?callback=?', function (data)
			{
				oThis.addPreDevCamps(data);
			}
		);
		
		oThis.tweetDiv.css('left',-500);
   		oThis.tweetDiv.css('top',-500);
		$('body').append(oThis.tweetDiv);
		oThis.getTwitterAPIDetails();
    });
};

/*
 * Getters and Setters for the Twitter user cache
 */
PreView.prototype.locGet = function (tweeter)
{
    return (typeof(this.tweeterDetails[tweeter.toLowerCase()]) === 'undefined')?null:this.tweeterDetails[tweeter.toLowerCase()].location;
};

PreView.prototype.locSet = function (tweeter,location)
{
    if((typeof(this.tweeterDetails[tweeter.toLowerCase()]) === 'undefined'))
    {
        this.tweeterDetails[tweeter.toLowerCase()] = {};
    }
    this.tweeterDetails[tweeter.toLowerCase()].location = location || '';
};

PreView.prototype.imgGet = function(tweeter)
{
    return (typeof(this.tweeterDetails[tweeter.toLowerCase()]) === 'undefined')?null:this.tweeterDetails[tweeter.toLowerCase()].image;
};

PreView.prototype.imgSet = function(tweeter,url)
{
    if(typeof(this.tweeterDetails[tweeter.toLowerCase()]) === 'undefined')
    {
        this.tweeterDetails[tweeter.toLowerCase()] = {};
    }
    this.tweeterDetails[tweeter.toLowerCase()].image = url || '';
};
/** End of Cache Methods **/

/*
 * Gets the Twitter API Details, such as what the current limit is and how long until it is reset
 *
 * Also sets a timer to refresh the API details
 */
PreView.prototype.getTwitterAPIDetails = function()
{
    var oThis = this;
    $.getJSON('http://twitter.com/account/rate_limit_status.json?callback=?',function(data)
        {
            oThis.twAPI.reqLimit = data.hourly_limit;
			oThis.twAPI.reqsRemaining = data.remaining_hits;
            oThis.twAPI.msecsUntilReset = (data.reset_time_in_seconds * 1000) - new Date().getTime();
            oThis.getLatestTweets();
            setTimeout(function(){oThis.getTwitterAPIDetails();},oThis.twAPI.msecsUntilReset);
            oThis.startProcessingTweets();
        }
    );
    
};

/*
 * Adds the preDevCamp icons to the map
 */
PreView.prototype.addPreDevCamps = function(pdcInfo)
{
    var oThis = this;
    var pdcMarkers = [];
    $.each(pdcInfo.cityInfo,function(idx,data)
        {
            pdcMarkers.push(oThis.getDevCampIcon(idx,data));
        }
    );
    
    this.markerMgr.addMarkers(pdcMarkers,0);
    this.markerMgr.refresh();
    
};

/*
 * Generates a preDevCamp icon
 */
PreView.prototype.getDevCampIcon = function(idx, pdcInfo)
{
    var preIcon = new GIcon(G_DEFAULT_ICON);
    preIcon.iconSize = new GSize(20,34);
    preIcon.iconAnchor = new GPoint(10,34);
    preIcon.image = "http://predevcamp.org/wp-content/themes/preDevCamp/images/mapIcon_pre.png";
    var markerOptions = {icon:preIcon,title:pdcInfo.name};
    var marker = new GMarker(new GLatLng(pdcInfo.lat,pdcInfo.long), markerOptions);
    GEvent.addListener(marker, "click", function()
    {
        parent.location.href='http://'+pdcInfo.domainName;                                          
    }); 
	return marker;
};

/*
 * Grab the latest Tweets
 */
PreView.prototype.getLatestTweets = function()
{
    var oThis = this;
    this.getTweetsTimerID = null;
    
    $.each(this.twitterURLs,function(searchType,queryURL){
        oThis.makeTwitterRequest(	"http://search.twitter.com/search.json?"+queryURL+"&callback=?",
                    				function(data){oThis.handleTweets(searchType,data);},
									true);
    });
};

/*
 * Handles Tweets by adding them to the TweetList... and nothing more
 */
PreView.prototype.handleTweets = function(searchType,data)
{
    var oThis = this;
    oThis.twitterURLs[searchType] = data.refresh_url;
    $.each(data.results,
		   function(idx,data)
		   {
			   oThis.tweets.put(data);
			}
	);
};


PreView.prototype.startProcessingTweets = function()
{
    var oThis = this;
    this.processTweetsTimerID = setTimeout(function(){oThis.processTweetList();},8000);  
};

PreView.prototype.stopProcessingTweets = function()
{
    clearTimeout(this.processTweetsTimerID);
};

PreView.prototype.processTweetList = function()
{
    var continueProcessing = true;
    if(this.tweets.tweets() > 0)
    {
        this.currentTweet = this.tweets.get();
        continueProcessing = this.locateTweet();
    }
    else
    {
        this.getLatestTweets();
    }
        
    if(continueProcessing)
    {
        this.startProcessingTweets();
    }
};

PreView.prototype.locateTweet = function()
{
    var oThis = this;
    if(this.locGet(this.currentTweet.from_user) === null)
    {
        if(!this.makeTwitterRequest("http://twitter.com/users/show/"+this.currentTweet.from_user+".json?callback=?",function(data)
            {
                oThis.locSet(data.screen_name,data.location);
                oThis.imgSet(data.screen_name,data.profile_image_url);
                oThis.locateTweet();
            }
        ))
        {
            /*
             * Failed to request the location, so put the tweet back on the list
             */
            this.tweets.put(this.currentTweet);
            this.currentTweet = null;
            return false;
        }
        else
        {
            return true;
        }
    }
    else
    {
        var tweetAddress = this.locGet(this.currentTweet.from_user);
        if (tweetAddress === 'undefined')
        {
            this.displayTweet();
        }
        else
        {       
            this.geoCoder.getLatLng(this.locGet(this.currentTweet.from_user),function(point)
                {
                    oThis.displayTweet(point);
                }
            );
        }
        return true;
    }
};

/*
 * Shows a Tweet on the map and pans to its location
 */
PreView.prototype.displayTweet = function(location)
{
    if (location === null)
    {
        location = new GLatLng(10,-130);
		$('img#arrow').css('visibility','hidden');
		$('div.tweetDiv').css('-moz-border-radius','5px');
		$('div.tweetDiv').css('-webkit-border-radius','5px');
    }
	else
	{
		$('img#arrow').css('visibility','visible');
		$('div.tweetDiv').css('-moz-border-radius','0px 5px 5px 5px');
		$('div.tweetDiv').css('-webkit-border-radius','0px 5px 5px 5px');
	}
	
    this.map.panTo(location);
    var tweetPoint = this.map.fromLatLngToContainerPixel(location);
   
	var profileImg = this.imgGet(this.currentTweet.from_user);
    if(profileImg === null)
    {
		profileImg = '';
	}
    $('div#tweeterImg img').attr('src',profileImg);

	
    $('div#tweeterText').html(this.currentTweet.text);
	var scrolling= $('div#'+this.mapDivID+' > div:first > div:first').position();
    this.tweetDiv.css('left',tweetPoint.x-scrolling.left);
    this.tweetDiv.css('top',tweetPoint.y-scrolling.top);
    $('div#'+this.mapDivID+' > div:first > div:first').append(this.tweetDiv);
};

/*
 * makeTwitterRequest
 *
 * Send a request to Twitter, after checking that we haven't exceeded the request limit
 * yet.
 */
PreView.prototype.makeTwitterRequest = function(req,cbFunc,noCost)
{
    var oThis = this;
    if (this.twAPI.reqsRemaining > 0)
    {
        if(typeof(noCost) === 'undefined')
        {
            this.twAPI.reqsRemaining -= 1; 
        }
        $.getJSON(req,cbFunc);
        $("div#tweetAPI").html("<span>Remaining: "+oThis.twAPI.reqsRemaining+"/"+oThis.twAPI.reqLimit+"</span>");
        return true;
    }
    else
    {
        this.stopProcessingTweets();
        return false;
    }
};

/*******************************
 * End of prototype definition *
 *******************************/

var pv = new PreView('preViewMap');