/**
 *
 * A hideously bastardised version of ...
 *
 * remy sharp / http://remysharp.com
 * Twitter / @rem
 * http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/
 *
 * @params
 *   cssIdOfContainer: e.g. twitters
 *   options: 
 *       {
 *           id: {String} username,
 *           count: {Int} 1-20, defaults to 1 - max limit 20
 *           prefix: {String} '%name% said', defaults to blank
 *           clearContents: {Boolean} true, removes contents of element specified in cssIdOfContainer, defaults to true
 *           ignoreReplies: {Boolean}, skips over tweets starting with '@', defaults to false
 *           template: {String} HTML template to use for LI element (see URL above for examples), defaults to predefined template
 *           enableLinks: {Boolean} linkifies text, defaults to true,
 *           newwindow {Boolean} opens links in new window, defaults to false
 *           timeout: {Int} How long before triggering onTimeout, defaults to 10 seconds if onTimeout is set
 *           onTimeoutCancel: {Boolean} Completely cancel twitter call if timedout, defaults to false
 *           onTimeout: {Function} Function to run when the timeout occurs. Function is bound to element specified with 
 *           cssIdOfContainer (i.e. 'this' keyword)
 *           callback: {Function} Callback function once the render is complete, doesn't fire on timeout
 *
 *      CURRENTLY DISABLED DUE TO CHANGE IN TWITTER API:
 *           withFriends: {Boolean} includes friend's status
 *
 *       }
 *
 * @license MIT (MIT-LICENSE.txt)
 * @version 1.13.3 - ify now supports lists
 * @date $Date$
 */

// to protect variables from resetting if included more than once
if (typeof renderTwitters != 'function')(function() {
    /** Private variables */

    // only used for the DOM ready, since IE & Safari require special conditions
    var browser = (function() {
        var b = navigator.userAgent.toLowerCase();

        // Figure out what browser is being used
        return {
            webkit: /(webkit|khtml)/.test(b),
            opera: /opera/.test(b),
            msie: /msie/.test(b) && !(/opera/).test(b),
            mozilla: /mozilla/.test(b) && !(/(compatible|webkit)/).test(b)
        };
    })();

    var guid = 0;
    var readyList = [];
    var isReady = false;

    var monthDict = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

    var dayDict = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

    /** Global functions */

    // based on Dustin Diaz's ify, but with my fixes :-)
    window.ify = function() {
        var entities = {
            '"': '&quot;',
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;'
        };

        return {
            "link": function(t) {
                return t.replace(/[a-z]+:\/\/[a-z0-9-_]+\.[a-z0-9-_:~%&\?#\/.=]+[^:\.,\)\s*$]/ig,
                function(m) {
                    return '<a href="' + m + '">' + ((m.length > 25) ? m.substr(0, 24) + '...': m) + '</a>';
                });
            },
            "at": function(t) {
                return t.replace(/(^|[^\w]+)\@([a-zA-Z0-9_]{1,15}(\/[a-zA-Z0-9-_]+)*)/g,
                function(m, m1, m2) {
                    return m1 + '@<a href="http://twitter.com/' + m2 + '">' + m2 + '</a>';
                });
            },
            "hash": function(t) {
                return t.replace(/(^|[^&\w'"]+)\#([a-zA-Z0-9_]+)/g,
                function(m, m1, m2) {
                    return m1 + '#<a href="http://search.twitter.com/search?q=%23' + m2 + '">' + m2 + '</a>';
                });
            },
            "clean": function(tweet) {
                return this.hash(this.at(this.link(tweet)));
            }
        };
    } ();

    // to create a public function within our private scope, we attach the
    // the function to the window object
    window.renderTwitters = function(obj, options) {
        // private shortcuts
        function node(e) {
            return document.createElement(e);
        }

        function text(t) {
            return document.createTextNode(t);
        }

        var target = document.getElementById(options.twitterTarget);
        var data = null;
        var section = node('section'),
        article,
        statusSpan,
        timeSpan,
        i,
        max = obj.length > options.count ? options.count: obj.length;

        for (i = 0; i < max && obj[i]; i++) {
            data = getTwitterData(obj[i]);

            if (options.ignoreReplies && obj[i].text.substr(0, 1) == '@') {
                max++;
                continue;
                // skip
            }

            article = node('article');

            if (options.template) {
                article.innerHTML = options.template.replace(/%([a-z_\-\.]*)%/ig,
                function(m, l) {
                    var r = data[l] + "" || "";
                    if (l == 'text' && options.enableLinks) r = ify.clean(r);
                    return r;
                });
            } else {
                statusSpan = node('span');
                statusSpan.className = 'twitterStatus';
                timeSpan = node('span');
                timeSpan.className = 'twitterTime';
                statusSpan.innerHTML = obj[i].text;
                // forces the entities to be converted correctly
                if (options.enableLinks == true) {
                    statusSpan.innerHTML = ify.clean(statusSpan.innerHTML);
                }

                timeSpan.innerHTML = relative_time(obj[i].created_at);

                if (options.prefix) {
                    var s = node('span');
                    s.className = 'twitterPrefix';
                    s.innerHTML = options.prefix.replace(/%(.*?)%/g,
                    function(m, l) {
                        return obj[i].user[l];
                    });
                    article.appendChild(s);
                    article.appendChild(text(' '));
                    // spacer :-(
                }

                article.appendChild(statusSpan);
                article.appendChild(text(' '));
                article.appendChild(timeSpan);
            }

            if (options.newwindow) {
                article.innerHTML = article.innerHTML.replace(/<a href/gi, '<a target="_blank" href');
            }

            section.appendChild(article);
        }

        if (options.clearContents) {
            while (target.firstChild) {
                target.removeChild(target.firstChild);
            }
        }

        target.appendChild(section);

        if (typeof options.callback == 'function') {
            options.callback();
        }
    };

    window.getTwitters = function(target, id, count, options) {
        guid++;

        if (typeof id == 'object') {
            options = id;
            id = options.id;
            count = options.count;
        }

        // defaulting options
        if (!count) count = 1;

        if (options) {
            options.count = count;
        } else {
            options = {};
        }

        if (!options.timeout && typeof options.onTimeout == 'function') {
            options.timeout = 10;
        }

        if (typeof options.clearContents == 'undefined') {
            options.clearContents = true;
        }

        // Hack to disable withFriends, twitter changed their API so this requires auth
        // http://getsatisfaction.com/twitter/topics/friends_timeline_api_call_suddenly_requires_auth
        if (options.withFriends) options.withFriends = false;

        // need to make these global since we can't pass in to the twitter callback
        options['twitterTarget'] = target;

        // default enable links
        if (typeof options.enableLinks == 'undefined') options.enableLinks = true;

        // this looks scary, but it actually allows us to have more than one twitter
        // status on the page, which in the case of my example blog - I do!
        window['twitterCallback' + guid] = function(obj) {
            if (options.timeout) {
                clearTimeout(window['twitterTimeout' + guid]);
            }
            renderTwitters(obj, options);
        };

        // check out the mad currying!
        ready((function(options, guid) {
            return function() {
                // if the element isn't on the DOM, don't bother
                if (!document.getElementById(options.twitterTarget)) {
                    return;
                }

                var url = 'http://www.twitter.com/statuses/' + (options.withFriends ? 'friends_timeline': 'user_timeline') + '/' + id + '.json?callback=twitterCallback' + guid + '&count=20&cb=' + Math.random();

                if (options.timeout) {
                    window['twitterTimeout' + guid] = setTimeout(function() {
                        // cancel callback
                        if (options.onTimeoutCancel) window['twitterCallback' + guid] = function() {};
                        options.onTimeout.call(document.getElementById(options.twitterTarget));
                    },
                    options.timeout * 1000);
                }

                var script = document.createElement('script');
                script.setAttribute('src', url);
                document.getElementsByTagName('head')[0].appendChild(script);
            };
        })(options, guid));
    };

    // GO!
    DOMReady();


    /** Private functions */

    function getTwitterData(orig) {
        var data = orig,
        i;
        for (i in orig.user) {
            data['user_' + i] = orig.user[i];
        }

        data.time = relative_time(orig.created_at);

        return data;
    }

    function ready(callback) {
        if (!isReady) {
            readyList.push(callback);
        } else {
            callback.call();
        }
    }

    function fireReady() {
        isReady = true;
        var fn;
        while (fn = readyList.shift()) {
            fn.call();
        }
    }

    // ready and browser adapted from John Resig's jQuery library (http://jquery.com)
    function DOMReady() {
        if (document.addEventListener && !browser.webkit) {
            document.addEventListener("DOMContentLoaded", fireReady, false);
        } else if (browser.msie) {
            // If IE is used, use the excellent hack by Matthias Miller
            // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
            // Only works if you document.write() it
            document.write("<scr" + "ipt id=__ie_init defer=true src=//:><\/script>");

            // Use the defer script hack
            var script = document.getElementById("__ie_init");

            // script does not exist if jQuery is loaded dynamically
            if (script) {
                script.onreadystatechange = function() {
                    if (this.readyState != "complete") return;
                    this.parentNode.removeChild(this);
                    fireReady.call();
                };
            }

            // Clear from memory
            script = null;

        } else if (browser.webkit) {
            // Continually check to see if the document.readyState is valid
            var safariTimer = setInterval(function() {
                // loaded and complete are both valid states
                if (document.readyState == "loaded" ||
                document.readyState == "complete") {

                    // If either one are found, remove the timer
                    clearInterval(safariTimer);
                    safariTimer = null;
                    // and execute any waiting functions
                    fireReady.call();
                }
            },
            10);
        }
    }

    function relative_time(time_value) {
        var values = time_value.split(" "),
        parsed_date = Date.parse(values[1] + " " + values[2] + ", " + values[5] + " " + values[3]),
        date = new Date(parsed_date),
        relative_to = (arguments.length > 1) ? arguments[1] : new Date(),
        delta = parseInt((relative_to.getTime() - parsed_date) / 1000),
        r = '';

        function formatTime(date) {
            var hour = date.getHours(),
            min = date.getMinutes() + "",
            ampm = 'AM';

            if (hour == 0) {
                hour = 12;
            } else if (hour == 12) {
                ampm = 'PM';
            } else if (hour > 12) {
                hour -= 12;
                ampm = 'PM';
            }

            if (min.length == 1) {
                min = '0' + min;
            }

            return hour + ':' + min + ' ' + ampm;
        }

        function validTime(date) {
            var hour = date.getHours()+ "",
            min = date.getMinutes() + "";

            if (hour.length == 1) {
                hour = '0' + hour;
            };


            if (min.length == 1) {
                min = '0' + min;
            };

            return hour + ':' + min + ':00' ;
        }

        function validDate(date) {
            var ds = date.toDateString().split(/ /),
            mon = date.getMonth() + 1,
            week = dayDict[date.getDay()],
            day = date.getDate() + '',
            dayi = parseInt(day),
            year = date.getFullYear(),
            thisyear = (new Date()).getFullYear();
            return year + '-' + mon + '-' + dayi + 'T';

        }

        function formatDate(date) {
            var ds = date.toDateString().split(/ /),
            mon = monthDict[date.getMonth()],
            week = dayDict[date.getDay()],
            day = date.getDate() + '',
            dayi = parseInt(day),
            year = date.getFullYear(),
            thisyear = (new Date()).getFullYear(),
            th = 'th';

            // anti-'th' - but don't do the 11th, 12th or 13th
            if ((dayi % 10) == 1 && day.substr(0, 1) != '1') {
                th = 'st';
            } else if ((dayi % 10) == 2 && day.substr(0, 1) != '1') {
                th = 'nd';
            } else if ((dayi % 10) == 3 && day.substr(0, 1) != '1') {
                th = 'rd';
            }

            if (day.substr(0, 1) == '0') {
                day = day.substr(1);
            }

            return week + ' ' + day + th + ' ' + mon + (thisyear != year ? ', ' + year: '');
        }

        delta = delta + (relative_to.getTimezoneOffset() * 60);

        /*      if (delta < 5) {
            r = 'less than 5 seconds ago';
        } else if (delta < 30) {
            r = 'half a minute ago';
        } else if (delta < 60) {
            r = 'less than a minute ago';
        } else if (delta < 120) {
            r = '1 minute ago';
        } else if (delta < (45*60)) {
            r = (parseInt(delta / 60)).toString() + ' minutes ago';
        } else if (delta < (2*90*60)) { // 2* because sometimes read 1 hours ago
            r = 'about 1 hour ago';
        } else if (delta < (24*60*60)) {
            r = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
        } else {
            if (delta < (48*60*60)) {
                r = formatTime(date) + ' yesterday';
            } else { */
	
r=	'<time datetime="'+ validDate(date) + validTime(date) + '" pubdate>'+ formatDate(date) + ' at ' + formatTime(date) +'</time>';
	
 //      r = formatDate(date) + ' at ' + formatTime(date) + ' |  ' + validDate(date) + validTime(date);
        // r = (parseInt(delta / 86400)).toString() + ' days ago';
        /*          }
        }
*/
        return r;
    }
})();
