// jQuery cycle plugin: http://malsup.com/jquery/cycle/

// Credit: http://groups.google.com/group/jquery-ui/msg/90e37a2d2bdb1278
String.prototype.template = function (o) { 
  return this.replace(/{([^{}]*)}/g, function (a, b) { 
    var r = o[b]; 
    return typeof r === 'string' || typeof r === 'number' ? r : a; 
  }); 
};

var twitterStatusUrl  = "http://twitter.com/statuses/show/";
var haiku_template    = "<div class='haiku' style='display:none;'>\n" +
                          "<div class='text'>\n" +
                            "{html}\n" +
                          "</div>\n" +
                          "<div class='author'><a href='http://twitter.com/{author}/status/{status_id}' title='Twitter haiku by @{author}' target='_new'>@{author}</a></div>\n" +
                          "<div class='hash_link'><a href='?h={status_id}'>#</a></div>"
                        "</div>\n"
var discussion_re     = new RegExp(/(RT\s)|@\w+/);
var link_re           = new RegExp(/http|www/i);

function targetIsTweet() {
  return window.location.href.match(/\d+$/);
}

// TODO: I think there is a hole here for deleted tweets that are not
//       found by the Twitter API. I tried to handle them after the
//       getJSON enclosure, but this would muck with valid tweets.
function collectAndDisplaySingleHaiku() {
  var url        = twitterStatusUrl + targetIsTweet()[0] + ".json?callback=?";
  
  $.getJSON(url, function(json) {
    if(haikuIsDiscussionOrLink(json)) {
      write404Haiku();
      return;
    }
    
    haiku = new Haiku(json);

    if(!haiku.valid()) {
      write404Haiku();
      return;
    }
    
    writeMarkup(haiku);
    $('.hash_link').css({'display': 'none'});
    registerDivCycleForSingleHaiku();
  });
}

function haikuIsDiscussionOrLink(status) {
  return status.text.match(discussion_re) || status.text.match(link_re);
}

function writeMarkup(haiku) {
  haiku.generate_html();
  $('#content').append(haiku_template.template(haiku));
}

var feedUrl  = "http://search.twitter.com/search.json?callback=?&q=%23haiku&rpp=100";
// TODO avoid recycle icon

function collectAndBuildHaiku() {
  $.getJSON(feedUrl + "&page=2", function(json2) {
    $.getJSON(feedUrl, function(json) {
      var results = json.results.concat(json2.results);
      since_id    = results[0].id;
    
      results = jQuery.grep(results, function(n, i) {
        return "en" == n.iso_language_code && !haikuIsDiscussionOrLink(n);
      });
    
      jQuery.each(results, function() {
        haiku = new Haiku(this);
        if(haiku.valid()) {
          writeMarkup(haiku);
        }
      });
    
      registerDivCycle(); 
    });
  });
}

// function registerDivCycle() {
//   $(function() {    
//     $('#content').cycle({ 
//       next:    '.haiku .text',
//       speed:   1500, 
//       timeout: 0 
//     });
//   });
// }

function registerDivCycle() {
  $(function() {    
    $('#content').cycle({ 
      next:    '.haiku .text',
      speed:   2000, 
      timeout: 8000
    });
  });
  setTimeout("$('#intro .text').click()", 1500);
}

function registerDivCycleForSingleHaiku() {
  $(function() {    
    $('#content').cycle({ 
      next:    '.haiku .text',
      speed:   2000, 
      timeout: 0
    });
  });
  setTimeout("$('#intro .text').click()", 1000);
}

function Haiku(tweet) {
  this.tweet      = tweet;
  this.author     = tweet.from_user || tweet.user.screen_name;
  this.split_text = null;
  this.status_id  = tweet.id;
  this.html       = null;
}

Haiku.prototype.generate_html = function() {
  var haiku_html = [];
  jQuery.each(this.text(), function() {
    haiku_html.push(jQuery.trim(this).replace(/\s+(\.\.\.|\.\.|---|--|-)$/, ''));
  });
  this.html = haiku_html.join("<br />");
}

Haiku.prototype.text = function() {
  if(null == this.split_text) {
    var text = this.tweet.text;
    this.split_text = text.replace(/#\S+/g, '').split(/\/\/|\/|~|::|\n|\*|•/);
    this.split_text = jQuery.grep(this.split_text, function(n, i) {
      return n.length > 10;
    });
  }

  return this.split_text;
}
// after trim of each line, replace tailing " ..." or " --" or " -"
Haiku.prototype.valid = function() {
  return 3 == this.text().length &&
    jQuery.trim(this.text()[0]).split(/\s+/).length <= 5 &&
    jQuery.trim(this.text()[1]).split(/\s+/).length <= 7 &&
    jQuery.trim(this.text()[2]).split(/\s+/).length <= 5;
}

function write404Haiku() {
  var errorHaiku = [
    "Spectacular tweets / Are often missed while one counts / Those damn syllables",
    "Think this link should work? / Maybe it should, perhaps not / Who are we to choose?",
    "haitotheku so / Sorry that we can't display / This surely great tweet",
    "Sometimes we have pain / In our heads when counting the / syllables per tweet",
    "Why so serious? / It's just a haiku, my friend / You can't win 'em all",
    "Of all the problems / You have to admit this is / Quite low on the pole",
    "Consider a site / That works all the time; how quaint / Keeps you on your toes",
    "Rather than worry / About unlinkable tweets / Consider world peace"
  ];
  
  var haikuChoice = errorHaiku[randomNumber(errorHaiku.length)];
  var haikuHtml   = haikuChoice.split(" / ").join("<br />");
  
  var fullMarkup  = "<div class='haiku' style='display:none;'>\n" +
                      "<div class='text'>\n" +
                        haikuHtml + "\n" +
                      "</div>\n" +
                      "<div class='author'>404 Not Found</div>\n" +
                    "</div>\n";
  $('#content').append(fullMarkup);
  registerDivCycleForSingleHaiku();
}

function randomNumber(max) {
  return Math.floor(Math.random()*max);
}