function Tweet (info) {
  this.tweet = JSON.parse(info);
  if (parseInt(this.tweet.latitude)==0 && parseInt(this.tweet.longitude)==0) return;
    
  Tweet.showRate();

  if (!Tweet.updatingDisplay) {
    this.latlng = new google.maps.LatLng(this.tweet.latitude,this.tweet.longitude);
    this.lr = Tweet.map.overlay.getProjection().fromLatLngToContainerPixel(this.latlng);
    Tweet.map.overlay.showHeat(this);
    if (!Tweet.suppressDisplay && (this.lr.x > 360 || this.lr.y > 280))
      this.buildInfoWindow();
    if (!Photo.suppressDisplay)
      Photo.extract(this);
  }
}

Tweet.startStream = function () {
  var url = "http://twittervision.com/stream?"+Tweet.getStreamParams();
  Streamer.start(url, function (json) { new Tweet(json); });
}

Tweet.prototype.buildInfoWindow = function() {
  var img = new Image(48,48);
  img.src = this.tweet.user.profile_image_url;
  img.setAttribute('class',"profile_image");
  var info = document.createElement('div');
  var infoText = document.createElement('span');
  var screenName = document.createElement('div');
  info.appendChild(img);
  info.appendChild(screenName);
  info.appendChild(infoText);
  screenName.innerHTML = this.tweet.user.screen_name;
  screenName.setAttribute('class', 'screenName');
  info.setAttribute('class',"infoWindow");
  this.text = this.compactText();
  
  info.style.display = 'none';
  infoText.innerHTML = this.text;
  info.style.background = "#" + (this.tweet.user.profile_sidebar_fill_color || "fff");
  info.style.color = "#" + (this.tweet.user.profile_text_color || "333");
  info.style.border = "2px solid #" + this.tweet.user.profile_sidebar_border_color;

  var calculatedHeight = (this.text.length / 59) * 32;
  if (calculatedHeight<48) calculatedHeight = 48;
  var fullHeight = calculatedHeight + 22;
  var fullWidth = 250 + 22;
  
  this.rotation = this.tweet.latitude *  0.004986655;
  info.style.webkitTransform = "rotate(" + this.rotation + "rad)";
  //info.style.MozTransform = info.style.webkitTransform;
  this.x_rotation_offset = 9; //(1-Math.cos(this.rotation))*fullWidth;
  this.y_rotation_offset = 5;  //Math.sin(this.rotation)*fullHeight;
  
  info.style.top = parseInt((this.lr.y-fullHeight)-this.y_rotation_offset) + 'px';
  info.style.left = parseInt((this.lr.x-fullWidth)+this.x_rotation_offset) + 'px';
  info.style.height = calculatedHeight + 'px';
  
  info.onmouseover = function () { $('.infoWindow').css('zIndex',90); this.style.zIndex = 100; }
  img.onload = function () {
    if (Tweet.suppressDisplay) return;
    $(document.body).append(info);
    $(info).fadeIn(300).delay(2300).fadeOut(3500, 'swing', function () {$(info).remove()} );
  }
}

Tweet.prototype.compactText = function () {
  var words = this.tweet.text.split(' ');
  var res = new Array;
  for (w in words) {
    var new_word = words[w];
    if (new_word.length > 15)
      new_word = words[w].substr(0,15) + "...";
    res.push(new_word);
  }
  var txt = res.join(' ');
  if (this.tweet.place)
    txt += "<div class='place'>in " + this.tweet.place.full_name + "</div>";
  return txt;
}

Tweet.showRate = function () {
  var rate = Streamer.current.getRate() / 100;
  if (rate==Tweet.rate) return;
  for (i=0; i<=10; i++) {
    var el = $('#unit'+i);
    var c = el.css('color');      
    if (i>rate)
      el.css('background', "#333");
    else
      el.css('background', c);
    var diff = rate-i;
    if (diff > 0 && diff < 1)
      el.css('opacity', diff);
    else
      el.css('opacity', 1.0);
  }
  Tweet.rate = rate;
}
  
Tweet.toggleTweets = function () {
  Tweet.suppressDisplay = !Tweet.suppressDisplay;
  var newColor;
  if (Tweet.suppressDisplay) {
    $('.infoWindow').remove(); 
    newColor = '#444';
  } else {
    newColor = '#eee';
  }
  $('#tweets').css('color',newColor);
}

// This should include all available parameters
Tweet.getStreamParams = function () {
  var params = new Array();

  options = {};
	var str = location.search.substring(1, location.search.length);

	if (!str.length < 1) {
  	// plus => space per http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
  	str = str.replace(/\+/g, ' ');
	
  	// extract name=value arguments
  	var args = str.split('&'); // parse out name/value pairs separated via &
  	var len = args.length;
  	var i;
	
  	for (i = 0; i < len; i++) {
  		var pair = args[i].split('=');
  		var name = decodeURIComponent(pair[0]);
  		 if (pair.length==2)
  			options[name] = decodeURIComponent(pair[1]);
  		else
  		 	options[name] = true;
  	}
  }

  // var q = $('#q');
  // if (q.length) params.push("keyword=" + q[0].value);
  if (!options.world) {
    if (navigator.geolocation) {
      var geoSuccess = function(position) {
        var loc = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        Tweet.map.gmap.setCenter(loc);
        Tweet.map.gmap.setZoom(8);
        Tweet.map.size();
      };

      var geoFail = function(geoError) { console.log(geoError); };

      console.log("requesting location");
      navigator.geolocation.getCurrentPosition(geoSuccess, geoFail, {timeout:10000});
    }
    
    params.push("locations=" + Tweet.map.gmap.getBounds().toUrlValue());
  }
  if (options.q) params.push("keyword=" + options.q);
  console.log(params);
  return params.join('&');
}

Tweet.suppressDisplay = false;
Tweet.startMap = function () {
  var loc = new google.maps.LatLng(39.8, -98.5);
  Tweet.map = new Map('map', loc);    
}



