$(function(){
        //snip
        //define email
        $("#email").fieldtag();

});

/**
 * Setup Item Expansion
 */





$(function(){
    window.twitRss2 = new RSS2($('#twitterItems'));
    window.newsRss2 = new RSS2($('#newsItems'), true);
    window.flickr2 = new Flickr($('#flickrItems'));

    twitRss2.setup();
    newsRss2.setup();
    flickr2.setup();

    flickr2.preload();


    
    var flickrContracted = 12;
    var flickrExpanded = 20;
    var rssContrated = 5;
    var rssExpanded = 11;
    var expandedText = '-';
    var contractedText = '+';


    var state = 'expanded';
    function toggleState() {
        if(state == 'contracted') {
            twitRss2.display(rssExpanded);
            newsRss2.display(rssExpanded);
            flickr2.display(flickrExpanded);

            $('#moreTwitterButton').text(expandedText);
            $('#moreNewsButton').text(expandedText);
            $('#moreFlickrButton').text(expandedText);

            state = 'expanded';
        } else {
            twitRss2.display(rssContrated);
            newsRss2.display(rssContrated);
            flickr2.display(flickrContracted);

            $('#moreTwitterButton').text(contractedText);
            $('#moreNewsButton').text(contractedText);
            $('#moreFlickrButton').text(contractedText);

            state = 'contracted';
        }
    }

    // set initial state to contracted
    toggleState();

    
    $('#moreTwitterButton').click(toggleState);
    $('#moreNewsButton').click(toggleState);
    $('#moreFlickrButton').click(toggleState);
})


/**
 * Setup YouTube
 */
$(function() {
    $('#youtube li').each(function() {
        var item = $(this);

        // get data from DOM
        var swfurl = $('a.stage', item).attr('href');
        var watchurl = $('a.text', item).attr('href');
        var title = $('a.text', item).text();



        // clear links so we can handle them instead
        $('a', item).attr('href', '#');

        $('a', item).click(function() {
            openYoutubePlayer(swfurl, title, watchurl);
        })
    });


});

function openYoutubePlayer(swfurl, title, watchurl) {
    var template = $('#templates #youtube-container').clone();
    var backdrop = $('#templates #backdrop').clone();



    $('#close', template).click(function() {
        template.remove();
        backdrop.remove();
    });

    $('#view-link', template).attr('href', watchurl);

    $('#youtube-stage', template).flash({
        swf: swfurl,
        flashvars: {
            autoplay: 1
        }
    });

    backdrop.css({
       height: $(document).height(),
       width: $(document).width()
    });

    $("body").append(backdrop);
    $("body").append(template);

    // update CSS after load, since height/width aren't set until then.
    template.css({
        left: ($(window).width() - $(template).width()) / 2,
        top: ($(window).height() - $(template).height()) / 2
    });
}

function Flickr(parentEl) {



    /**
     * Setup Flickr
     */
    var numDisplayed = 0;

 

    function setupFlickr() {

        var flickrHover = null;
        var isTop = false;

        // add setup thumbnail image
        $('li', parentEl).each(function () {
            var src = $(this).attr("data-thumbnail");
            var link = $("<a/>").attr('href', $(this).attr('data-link')).attr('target', '_blank');
            var thumb = $("<img/>").attr("src", src);
            link.append(thumb);
            $(this).append(link);
        });

        // mouseenter
        $('li', parentEl).mouseenter(function (e) {

            var img = $(this);
            flickrHover = openFlickr(img.attr('data-image'), img.attr('data-title'), img.attr('data-author'));

            var bottomOfViewport = $(window).scrollTop() + $(window).height();
            // FIXME img.position() is relative to parent, not document...
            var bottomOfFlickrHover = img.position().top + img.height() + flickrHover.height();

            isTop = bottomOfFlickrHover > bottomOfViewport;
        });

        // mouseleave
        $('li', parentEl).mouseleave(function (e) {
            flickrHover.remove();
        });

        $('li', parentEl).mousemove(function(e) {

            if(isTop) {
                flickrHover.css({
                    top: e.pageY - 12 - flickrHover.height(),
                    left: e.pageX + 4
                });
            } else {
                flickrHover.css({
                    top: e.pageY + 4,
                    left: e.pageX + 4
                });
            }
        });
    }

    function preloadFlickr() {
        // preload flickr images
        $('li img', parentEl).each(function () {
            var src = $(this).attr("data-image");
            log("preloading "+src);
            $("<img>").attr("src", src);
        });


    }

    function openFlickr(imgurl, title, author) {
        var template = $('#templates #flickr-container').clone();

        $('#flickr-stage img', template).attr('src', imgurl);
        $('#flickr-info .title', template).text(title);
        $('#flickr-info .author', template).text(author);

        $('body').append(template);

        return template;
    }

    function displayItems(count) {
        numDisplayed = count;
        $('li', parentEl).each(function(i) {
            if(i < count)  {
                $(this).addClass('visible');
            } else {
                $(this).removeClass('visible');
            }
        })
    }

    return {
        setup: setupFlickr,
        preload: preloadFlickr,
        display: displayItems,
        numDisplayed: function() {return numDisplayed;}
    }
}



debugMode = false;
function log(msg) {
    if(debugMode) {
        console.log(msg);
    }
}






/**
 * Setup the email form to submit via ajax and go blank on focus.
 */
$(function() {

    $('#fieldset form').submit(function() {
       var form = $(this);
       var data = form.serializeArray();

       if(!isValidEmailAddress(data[0].value)) {
           alert("Please enter a valid email address.");
           return false;
       }

       $.post(this.action, data, function(result) {
           form.replaceWith(result);
       });

       return false;
    });
})

// from http://www.reynoldsftw.com/2009/03/live-email-validation-with-jquery/
function isValidEmailAddress(emailAddress) {
    var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
    return pattern.test(emailAddress);
}


// Simulates PHP's date function
// modified from: http://jacwright.com/projects/javascript/date_format
function DateUtil(date) {
    var replaceChars = {
	shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
	longMonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
	shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
	longDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],

	// Day
	d: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); },
	D: function() { return replaceChars.shortDays[this.getDay()]; },
	j: function() { return this.getDate(); },
	l: function() { return replaceChars.longDays[this.getDay()]; },
	N: function() { return this.getDay() + 1; },
	S: function() { return (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th'))); },
	w: function() { return this.getDay(); },
	z: function() { return "Not Yet Supported"; },
	// Week
	W: function() { return "Not Yet Supported"; },
	// Month
	F: function() { return replaceChars.longMonths[this.getMonth()]; },
	m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
	M: function() { return replaceChars.shortMonths[this.getMonth()]; },
	n: function() { return this.getMonth() + 1; },
	t: function() { return "Not Yet Supported"; },
	// Year
	L: function() { return "Not Yet Supported"; },
	o: function() { return "Not Supported"; },
	Y: function() { return this.getFullYear(); },
	y: function() { return ('' + this.getFullYear()).substr(2); },
	// Time
	a: function() { return this.getHours() < 12 ? 'am' : 'pm'; },
	A: function() { return this.getHours() < 12 ? 'AM' : 'PM'; },
	B: function() { return "Not Yet Supported"; },
	g: function() { return this.getHours() % 12 || 12; },
	G: function() { return this.getHours(); },
	h: function() { return ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12); },
	H: function() { return (this.getHours() < 10 ? '0' : '') + this.getHours(); },
	i: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
	s: function() { return (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(); },
	// Timezone
	e: function() { return "Not Yet Supported"; },
	I: function() { return "Not Supported"; },
	O: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + '00'; },
	T: function() { var m = this.getMonth(); this.setMonth(0); var result = this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); this.setMonth(m); return result;},
	Z: function() { return -this.getTimezoneOffset() * 60; },
	// Full Date/Time
	c: function() { return "Not Yet Supported"; },
	r: function() { return this.toString(); },
	U: function() { return this.getTime() / 1000; }
    };

    function format(format) {
	var returnStr = '';
	for (var i = 0; i < format.length; i++) {
		var curChar = format.charAt(i);
		if (replaceChars[curChar]) {
			returnStr += replaceChars[curChar].call(date);
		} else {
			returnStr += curChar;
		}
	}
	return returnStr;
    }

    return {
        format: format
    }
}


function RSS2(ul, skipHtml) {
    var selectedItem = null;
    var numDisplayed = 0;


    function setupItemsData() {
        $('li', ul).each(function(i) {
            $(this).click(function() {
                clickItem(this);
            })

        });
    }

    // the initial function that is used to display n items
    function displayItemsData(count) {
        numDisplayed = count;
        $('li', ul).each(function(i) {
            if(i < count) {
                // toggle it to get the HTML setup
                clickItem(this);
            } else {
                hideItem(this);
            }
        });

        // select the first item initially
        clickItem($('li:first-child', ul));

    }

    function hideItem(li) {
        $(li).removeClass('selected').removeClass('deselected');
    }


    // if an item is not selected then select it. deselect any selected item.
    function clickItem(li) {
        li = $(li);

        var isNew = !li.hasClass("selected") && !li.hasClass("deselected");

        // if the item is selected or new
        if(isNew || li.hasClass("deselected")) {

            // remove the css selected class
            selectedItem && setDeselectedHtml(selectedItem);

            // remove the css deselected class
            setSelectedHtml(li);
            selectedItem = li;
        } 
    }
    
    function setDeselectedHtml(li) {
        // get the body text from the body data attribute
        var body = li.attr("data-body");
        var timestamp = li.attr("data-timestamp");
        var author = li.attr("data-author");
        
        // add deselected html, including truncated body
        li.removeClass('selected').addClass('deselected');
        li.empty();
        li.append('<span class="body"/><a class="more" href="#">more</a>');
        $('.body', li).text(stripHTML(body).substr(0, 35)+'...');
    }

    function setSelectedHtml(li) {
        // get the body text from the body data attribute
        var body = li.attr("data-body");
        var timestamp = li.attr("data-timestamp");
        var author = li.attr("data-author");

        // add deselected html, including truncated body
        li.removeClass('deselected').addClass('selected');
        li.empty();
        li.append('<p class="body"/>');


        // if there is an author, add that
        if(author) {
            var authorInfo = $('<p><span class="time"/> from <span class="author"/></p>');
            var date = new Date(Date.parse(timestamp));
            if(date) {
                date = new DateUtil(date).format("g:i A M jS");
            } else {
                date = timestamp;
            }

            $('.time', authorInfo).text(date);
            $('.author', authorInfo).text(author);
            li.append(authorInfo);
        }

        if(!skipHtml) {
            $('.body', li).html(replaceURLWithHTMLLinks(body));
        } else {
            $('.body', li).html(body);
        }
    }

    function stripHTML(text) {
        var re= /<\S[^><]*>/g;

        return text.replace(re, "");
    }

    function replaceURLWithHTMLLinks(text) {
        var expLink = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/i;
        var expTwit = /\@([a-z0-9_]+)/i;

        var html = text.replace(expLink,"<a href='$1' target='_blank'>$1</a>");
        html = html.replace(expTwit,"<a href='http://twitter.com/$1' target='_blank'>@$1</a>");

        return html;
    }

    return {
        setup: setupItemsData,
        display: displayItemsData,
        numDisplayed: function() { return numDisplayed; }
    }
}
