﻿$(document).ready(function() {
    //$(".tabs").idTabs();
    $(".ui-tabs").tabs({
        load: function(event, ui) {
            OperapaediaKeywords();
        }
    });
    if ($.cookie("text-size") == "large") {
        $("body").addClass("text-large");
    }
    $(".expandable-link").click(function() {
        $(".expandable-content", $(this).parent()).toggle();
    });
    $("ul.sf-menu").superfish();
    $(".boxy").boxy();
    $(".modal-boxy").boxy({
        modal: true
    });
    $(".modal-boxy-flash").boxy({
        modal: true,
        afterShow: function() {
            startFlash();
            $("body").append("<style class=\"boxyflash\" type=\"text/css\">.boxy-content{padding:0px;}</style>");
        },
        afterHide: function() {
            $(".boxyflash").remove();
        }
    });
    $("textarea[maxlength]").each(function() {
        $(this).before("<div class=\"charsleft\"><span>" + $(this).attr("maxlength") + "</span> characters remaining.</div>");
        $field = $(this);
        $(this).keyup(function() {
            var l = $field.val().length;
            var maxl = parseInt($field.attr("maxlength"));
            if (!isNaN(maxl)) {
                $field.prev(".charsleft").html("<span>" + (maxl - l) + "</span> characters remaining.");
            }
        });
    });
    /*
    $(".btn").prepend("<span class=\"l\"></span><span class=\"r\"></span>");
    //$(".btn").append("<div class=\"clear\"></div>");
    $(".btn").hover(function() {
        $(this).addClass("hover");
    },
    function() {
        $(this).removeClass("hover");
    });
    */
    //tooltips
    //fancy tip like boxy
    $('.tip').bstip({
        color: "bswrap"
    });
    $(".videoLink").click(function() {
        stopAllAudio();
        var videosrc = $("a", $(this)).attr("href");
        if (videosrc == "#view") {
            videosrc = $("a", $(this)).attr("vsource");
        }
        $("a", $(this)).attr("href", "#view");
        $("a", $(this)).attr("vsource", videosrc);
        var vw = parseInt($("a", $(this)).attr("videowidth"));
        var vh = parseInt($("a", $(this)).attr("videoheight")) + 40;
        var vt = $(".videoTitle", $(this)).html();
        var vd = $(".videoDescription", $(this)).html();
        var videoboxy = new Boxy("<div style=\"width:" + vw + "px;height:" + vh + "px; background-color:#000000; padding:0px;\"><div id=\"video1\" style=\"z-index: 0;\"></div></div>", {
            "title": vt,
            modal: true,
            unloadOnHide: true,
            afterShow: function() {
                $("#video1").flash({
                    swf: '/Content/flash/video_single.swf',
                    height: vh,
                    width: vw,
                    params: {
                        wmode: "transparent",
                        flashvars: {
                            myPath: videosrc
                        }
                    }
                });
            }
        });
    });
    $(".youTubeLink").click(function() {
        stopAllAudio();
        var videosrc = $("a", $(this)).attr("href");
        if (videosrc == "#view") {
            videosrc = $("a", $(this)).attr("vsource");
        }
        var vidID = videosrc.substring(31);
        $("a", $(this)).attr("href", "#view");
        $("a", $(this)).attr("vsource", videosrc);
        var vw = parseInt($("a", $(this)).attr("videowidth"));
        var vh = parseInt($("a", $(this)).attr("videoheight"));
        var vt = $(".videoTitle", $(this)).html();
        var vd = $(".videoDescription", $(this)).html();
        var videoContent = "<object width=\"" + vw + "\" height=\"" + vh + "\"><param name=\"movie\" value=\"http://www.youtube.com/v/" + vidID + "&hl=en&fs=1&\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/" + vidID + "&hl=en&fs=1&\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"" + vw + "\" height=\"" + vh + "\" wmode=\"transparent\"></embed></object>";
        var videoboxy = new Boxy("<div style=\"width:" + vw + "px; height:" + vh + "px; padding:0px; margin:0px;\" id=\"video1\">" + videoContent + "</div>", {
            "title": vt,
            modal: true
        });
    });
    $(".audio.podcast").each(function(i) {
        var ind = "podcast" + i;
        var audiourl = $(this).attr("href");
        var autoplay = false;
        if ($(this).attr("autoplay") != undefined && $(this).attr("autoplay") == "true") {
            autoplay = true;
        }
        var plyrhtml = '';
        plyrhtml += '<div id="jquery_jplayer_' + ind + '" class="audioplayer"></div><div id="player_container_' + ind + '" class="audiodisplay ' + $(this).attr("class") + '"><ul class="player_controls">';
        plyrhtml += '<li id="player_play_' + ind + '" class="player_play"><span>play</span></li>';
        plyrhtml += '<li id="player_pause_' + ind + '" class="player_pause"><span>pause</span></li></ul>';
        plyrhtml += '<div id="player_progress_' + ind + '" class="player_progress"><div id="player_progress_load_bar_' + ind + '" class="player_progress_load_bar">';
        plyrhtml += '<div id="player_progress_play_bar_' + ind + '" class="player_progress_play_bar"></div></div></div></div>';
        $(this).after(plyrhtml);
        $("#jquery_jplayer_" + ind).jPlayer({
            ready: function() {
                if (autoplay) {
                    $("#jquery_jplayer_" + ind).changeAndPlay(audiourl);
                } else {
                    $("#jquery_jplayer_" + ind).change(audiourl);
                }
            },
            swfPath: "/Scripts"
        });

        $("#jquery_jplayer_" + ind).jPlayerId("play", "player_play_" + ind);
        $("#jquery_jplayer_" + ind).jPlayerId("pause", "player_pause_" + ind);
        $("#jquery_jplayer_" + ind).jPlayerId("loadBar", "player_progress_load_bar_" + ind);
        $("#jquery_jplayer_" + ind).jPlayerId("playBar", "player_progress_play_bar_" + ind);
        $("#jquery_jplayer_" + ind).onSoundComplete(function() {
            $("#jquery_jplayer_" + ind).play();
        });
        $("#player_play_" + ind).click(function() {

            stopAllAudio();
            $('#jquery_jplayer_' + ind).play();
        });
        $("#player_pause_" + ind).click(function() {
            $('#jquery_jplayer_' + ind).pause();
        });
        $(this).hide();
    });

    $(".audio.opera").each(function(i) {
        var ind = "opera" + i;
        var audiourl = $(this).attr("href");
        var title = $(this).html();
        var autoplay = false;
        if ($(this).attr("autoplay") != undefined && $(this).attr("autoplay") == "true") {
            autoplay = true;
        }
        var plyrhtml = '';
        plyrhtml += '<div id="jquery_jplayer_' + ind + '" class="audioplayer"></div><div id="player_container_' + ind + '" class="audiodisplay ' + $(this).attr("class") + '"><ul class="player_controls">';
        plyrhtml += '<li id="player_play_' + ind + '" class="player_play"><span>play</span></li>';
        plyrhtml += '<li id="player_pause_' + ind + '" class="player_pause"><span>pause</span></li></ul>';
        plyrhtml += '<div id="audio_title_' + ind + '" class="audio_title"><span>' + title + '</span></div>';
        plyrhtml += '<div id="player_progress_' + ind + '" class="player_progress"><div id="player_progress_load_bar_' + ind + '" class="player_progress_load_bar">';
        plyrhtml += '<div id="player_progress_play_bar_' + ind + '" class="player_progress_play_bar"></div></div></div></div>';
        $(this).after(plyrhtml);
        $("#jquery_jplayer_" + ind).jPlayer({
            ready: function() {
                if (autoplay) {
                    $("#jquery_jplayer_" + ind).changeAndPlay(audiourl);
                    $("#audio_title_" + ind).animate({ width: ($("#audio_title_" + ind + " span").width() + 65) + "px" }, { duration: 3000, easing: 'linear' });
                } else {
                    $("#jquery_jplayer_" + ind).change(audiourl);
                }
            },
            swfPath: "/Scripts"
        });
        $("#jquery_jplayer_" + ind).jPlayerId("play", "player_play_" + ind);
        $("#jquery_jplayer_" + ind).jPlayerId("pause", "player_pause_" + ind);
        $("#jquery_jplayer_" + ind).jPlayerId("loadBar", "player_progress_load_bar_" + ind);
        $("#jquery_jplayer_" + ind).jPlayerId("playBar", "player_progress_play_bar_" + ind);
        $("#jquery_jplayer_" + ind).onSoundComplete(function() {
            $("#jquery_jplayer_" + ind).play();
        });
        $("#player_play_" + ind).click(function() {
            stopAllAudio();
            $('#jquery_jplayer_' + ind).play();
            $("#audio_title_" + ind).animate({ width: ($("#audio_title_" + ind + " span").width() + 65) + "px" }, { duration: 3000, easing: 'linear' });
        });
        $("#player_pause_" + ind).click(function() {
            $('#jquery_jplayer_' + ind).pause();
            $("#audio_title_" + ind).animate({ width: "0px" }, { duration: 2000, easing: 'linear' });
        });
        $(this).hide();
    });

    $("form").submit(function() {
        if ($(".required-field").val() != undefined && $(".required-field").val() != "") {
            return false;
        }
    });
    $("input").focus(function() {
        if (!$(this).hasClass("no-focus")) {
            $(this).addClass("focus");
        }
    });
    $("input").blur(function() {
        $(this).removeClass("focus");
    });
    $("textarea").focus(function() {
        $(this).addClass("focus");
    });
    $("textarea").blur(function() {
        $(this).removeClass("focus");
    });

    FormEffects();
    jQuery.validator.addMethod("defaultInvalid",
    function(value, element) {
        return value != element.defaultValue;
    },
    "");
    jQuery.validator.addMethod("phoneUS",
    function(phone_number, element) {
        phone_number = phone_number.replace(/\s+/g, "");
        return this.optional(element) || phone_number.length > 9 && phone_number.match(/^(\(?\d\d\d\)?)?( |-|\.)?\d\d\d( |-|\.)?\d{4,4}(( |-|\.)?[x]+ ?\d+)?$/);
    },
    "Please specify a valid phone number");
    jQuery.validator.addMethod("zipcodeUS",
    function(zip_code, element) {
        zip_code = zip_code.replace(/\s+/g, "");
        return this.optional(element) || zip_code.length > 4 && zip_code.match(/^\d{5}$/);
    },
    "Please specify a valid postal code");

    //    jQuery.validator.addMethod("billingRequired", function(value, element) {
    //        if ($("#bill_to_co").is(":checked"))
    //            return $(element).parents(".subTable").length;
    //        return !this.optional(element);
    //    }, "");
    jQuery.validator.messages.required = "";


    $(".resize").vjustify();
    //$("div.buttonSubmit").hoverClass("buttonSubmitHover");
    if ($.browser.safari) {
        $("body").addClass("safari");
    }

    $("input.phone").mask("(999) 999-9999? x9999");
    $("input.zipcode").mask("99999");
    $("input.digits").numeric();

});

$(window).load(function() {
    //equal height cols
    //    var c1 = $(".equal", $("#col1")).height();
    //    var c2 = $("#col2").height() - 12;
    //    var c1p = parseInt($(".equal", $("#col1")).css("padding-top")) + parseInt($(".equal", $("#col1")).css("padding-bottom"));

    //    if (c1 < c2) {
    //        $(".equal", $("#col1")).css("height", (c2 - c1p) + "px");
//    }

$("#footerSponsors").append('<li><a href="http://www.foley.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Foley.gif" alt="Foley and Lardner LLP - Friday Series Sponsor" border="0" /></a><br />Friday Series Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.ntrs.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/NorthernTrust.gif" alt="Northern Trust - Corporate Producing Partner" border="0" /></a><br />Corporate Producing Partner</li>');
$("#footerSponsors").append('<li><a href="http://www.qualcomm.com" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Qualcomm.gif" alt="Qualcomm - Major Education Sponsor" border="0" /></a><br />Major Education Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.usbank.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/usbank.gif" alt="US Bank - Saturday Series Sponsor" border="0" /></a><br />Saturday Series Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.sempra.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/SempraEnergy.gif" alt="Sempra Energy - Major Education Sponsor" border="0" /></a><br />Major Education Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.sycuan.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/SycuanCasino.gif" alt="Sycuan Casino - Major Sponsor" border="0" /></a><br />Major Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.db.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/DeutscheBank.gif" alt="Deutsche Bank - Corporate Producing Partner" border="0" /></a><br />Corporate Producing Partner</li>');
$("#footerSponsors").append('<li><a href="http://www.goodwinprocter.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/GoodwinProcter.gif" alt="Goodwin Procter - Corporate Producing Partner" border="0" /></a><br />Corporate Producing Partner</li>');
$("#footerSponsors").append('<li><a href="http://www.americanexpress.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/AmericanExpress.gif" alt="American Express - The Official Card of the 2011 International Season" border="0" /></a><br />The Official Card of the 2011 International Season</li>');
$("#footerSponsors").append('<li><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Coyle_logo.jpg" alt="Courtney Ann Coyle, Attorney at Law - Supertitles Sponsor" border="0" /><br />Supertitles Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.wellsfargo.com/theprivatebank/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Wells Fargo_PrivateBank_logo.gif" alt="Wells Fargo Private Bank - Post-Opera Cast Parties Sponsor" border="0" /></a><br />Post-Opera Cast Parties Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.nuvasive.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Nuvasive.gif" alt="NuVasive - Major Sponsor" border="0" /></a><br />Major Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.signonsandiego.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Union-Tribune.gif" alt="Union-Tribune - Major Education Sponsor" border="0" /></a><br />Major Education Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.www.lamar.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/Lamar.gif" alt="Lamar - Major Sponsor" border="0" /></a><br />Major Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.www.aceparking.com/" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/acelogo.gif" alt="Ace Parking - Major Education Sponsor" border="0" /></a><br />Major Education Sponsor</li>');
$("#footerSponsors").append('<li><a href="http://www.jpmorgan.com/pages/jpmorgan/private_banking" target="_blank"><img src="https://s3.amazonaws.com/sdo.media/logos/FooterSponsors/JPMorgan" alt="J.P. Morgan - Major Education Sponsor" border="0" /></a><br />Major Education Sponsor</li>');

$('#footerSponsors').innerfade({
    speed: '4000',
    timeout: 4000,
    type: 'sequence',
    containerheight: '100px'
});
    if (window.location.href.indexOf('SessionExpired') < 0) {
        GenerateTimer();
    }
    $(".first-field").focus();
    if ($.browser.msie) {
        $("object", $(".audio")).each(function() {
        var shtml = $(this).parent().html();
        alert(shtml);
        $(this).parent().html(shtml);
        });
    }
    OperapaediaKeywords();
});
var keywords;
function OperapaediaKeywords() {
    if (keywords == undefined) {
        $.getJSON("/json/OperapaediaKeywords/",
            function(data) {
                keywords = data;
                if (data.length > 0) {
                    for (k = 0; k < data.length; k++) {
                        $("p", $("#col1")).linkKeywords(keywords[k]);
                        $("li", $("#col1")).linkKeywords(keywords[k]);
                        $("dl", $("#col1")).linkKeywords(keywords[k]);
                        $("p", $("#mainoperapane")).linkKeywords(keywords[k]);
                        $("li", $("#mainoperapane")).linkKeywords(keywords[k]);
                    }
                }
            });
        } else {
        if (keywords.length > 0) {
            for (k = 0; k < keywords.length; k++) {
                $("p", $("#col1")).linkKeywords(keywords[k]);
                $("li", $("#col1")).linkKeywords(keywords[k]);
                $("dl", $("#col1")).linkKeywords(keywords[k]);
                $("p", $("#mainoperapane")).linkKeywords(keywords[k]);
                $("li", $("#mainoperapane")).linkKeywords(keywords[k]);                
            }
        }
    }
}


jQuery.fn.linkKeywords = function(pat) {
    function innerLink(node, pat) {
        var skip = 0;
        if (node.nodeType == 3) {
            var pos = node.data.toUpperCase().indexOf(pat);
            if (pos >= 0 ) {
                var spannode = document.createElement('a');
                spannode.className = 'keyword';
                spannode.target = "_blank";
                spannode.href = "/Operapaedia/" + pat.toLowerCase();
                var middlebit = node.splitText(pos);
                var endbit = middlebit.splitText(pat.length);
                var middleclone = middlebit.cloneNode(true);
                spannode.appendChild(middleclone);
                middlebit.parentNode.replaceChild(spannode, middlebit);
                skip = 1;
            }
        }
        else if (node.nodeType == 1 && node.childNodes && !/(script|style|a|h1|q|select)/i.test(node.tagName)) {
            for (var i = 0; i < node.childNodes.length; ++i) {
                i += innerLink(node.childNodes[i], pat);

            }
        }
        return skip;
    }
    return this.each(function() {
        innerLink(this, pat.toUpperCase());
    });
};


$.fn.vjustify = function() {
    var maxHeight = 0;
    $(".resize").css("height", "auto");
    this.each(function() {
        if (this.offsetHeight > maxHeight) {
            maxHeight = this.offsetHeight;
        }
    });
    this.each(function() {
        $(this).height(maxHeight);
        if (this.offsetHeight > maxHeight) {
            $(this).height((maxHeight - (this.offsetHeight - maxHeight)));
        }
    });
};

$.fn.hoverClass = function(classname) {
    return this.hover(function() {
        $(this).addClass(classname);
    },
    function() {
        $(this).removeClass(classname);
    });
};

function ToggleText(mode) {
    if (mode == 1) {
        $("body").addClass("text-large");
        $.cookie("text-size", "large", {"path": "/"});
    } else {
    $("body").removeClass("text-large");
    $.cookie("text-size", null,{"path": "/"});
    }
}

function GenerateTimer() {
    $.getJSON("/json/GetTicketExpiration/" + dateFormat(new Date(), "yymmdd_hhMMss"),
    function(json) {
        if (json.d != "TESSITURA_SEAT_LOCKING_EXCEPTION") {
            var expiration = parseInt(json);
            var sCartTimer = "";
            var secondsRemaining = expiration;
            //alert(expiration + ' seconds remaining');
            var timeRemaining = Math.floor(secondsRemaining / 60);
            if (timeRemaining < 30) {
                if (timeRemaining > 1) {
                    $("div.timer").html("You have " + timeRemaining + " minutes remaining to complete your order").show();
                    setTimeout("UpdateTimer(" + timeRemaining + ")", 60000);

                }
                else {
                    window.location = '/Account/SessionExpired/';
                }
            }
        }
    });

}

function UpdateTimer(currentTime) {
    currentTime -= 1;
    if (currentTime > 0) {
        $("div.timer").html("You have " + currentTime + " minutes remaining to complete your order");
        setTimeout("UpdateTimer(" + currentTime + ")", 60000);
    }
    else {
        window.location = '/Account/SessionExpired';
    }
}
function FormEffects() {
    //radio hotspots
    $("input[type=radio]", $(".radio-hotspot")).click(radioClickHandler);

    $(".radio-hotspot").removeClass("selected").attr("sel", "false");
    $(".radio-hotspot").each(function(ind, el) {
        if ($("input[type=radio]:checked", $(el)).length > 0) {
            $(el).addClass("selected").attr("sel", "true");
        }
        $(el).attr("customtype", "radio-hotspot");
    });
    //checkbox hotspots
    $("input[type=checkbox]", $(".checkbox-hotspot")).click(checkboxClickHandler);

}

function radioClickHandler(event) {
    //event.stopPropagation();
    $(".radio-hotspot").removeClass("selected").attr("sel", "false");
    $(".radio-hotspot").each(function(ind2, el2) {
        if ($("input[type=radio]:checked", $(el2)).length > 0) {
            $(el2).addClass("selected");
            $(el2).attr("sel", "true");
        }
    });
}

function stopAllAudio() {
     $(".audioplayer").each(function(ind) {
     //alert($(this).attr("id"));
                try{
     $(this).stopAudio();
            }catch(err){}});
            $(".audio_title").animate({ width: "0px" }, { duration: 2000, easing: 'linear' });
}

function stopAudioJS(src) {
    alert("src: "+ src);
    $("object", $(".audio")).each(function() {
        if ($(this).attr("id") != src) {
            try {
                thisMovie($(this).attr("id")).haltAudio();
            }
            catch (err) { alert(err.description); }
        }
    });
    $("embed", $(".audio")).each(function() {
        if ($(this).attr("name") != src) {
            try {
                thisMovie($(this).attr("name")).haltAudio();
            }
            catch (err) { }
        }
    });
}

function Search(q) {
    $.getJSON("/json/Search/?q=" + escape(q),
            function(data) {
                var content = "<div class=\"search-results\">";
                    if (data.length > 0) {
                    for (i = 0; i < data.length; i++) {
                        content += "<div class=\"search-result\">";
                        content += "<h3><a href=\"" + data[i].Url + "\" target=\"_blank\">" + data[i].Title + "</a></h3>";
                        content += "<p>" + data[i].Summary + "</p></div>";
                    }
                    
                } else {
                content += "<div>Your search '" +q+ "' did not return any valid results.</div>";
                }
                content += "</div>";

                var searchboxy = new Boxy(content, {
                    "title": "San Diego Opera Search Results for '" + q + "'",
                    modal: true,
                    unloadOnHide: true
                });
            });
}

function thisMovie(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return document.getElementById(movieName);
    }
    else {
        return document[movieName];
        //return document.getElementById(movieName);
    }
}

function checkboxClickHandler(event) {
    //event.stopPropagation();
    $(event.target).parent(".checkbox-hotspot").toggleClass("selected");
}

function padRight(str, len) {
    var s = str;
    var numspaces = len - str.length;
    if (numspaces > 0) {
        for (i = 0; i < numspaces; i++) {
            s += '&nbsp;';
        }
    }
    return s;
}
function padLeft(str, len) {
    var s = str;
    var numspaces = len - str.length;
    if (numspaces > 0) {
        for (i = 0; i < numspaces; i++) {
            s = '&nbsp;'+s;
        }
    }
    return s;
}

//dateFormat
/*
* Date Format 1.2.2
* (c) 2007-2008 Steven Levithan <stevenlevithan.com>
* MIT license
* Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
*
* Accepts a date, a mask, or a date and a mask.
* Returns a formatted version of the given date.
* The date defaults to the current date/time.
* The mask defaults to dateFormat.masks.default.
*/
var dateFormat = function() {
    var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
    timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
    timezoneClip = /[^-+\dA-Z]/g,
    pad = function(val, len) {
        val = String(val);
        len = len || 2;
        while (val.length < len) val = "0" + val;
        return val;
    };

    // Regexes and supporting functions are cached through closure
    return function(date, mask, utc) {
        var dF = dateFormat;

        // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
        if (arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) {
            mask = date;
            date = undefined;
        }

        // Passing date through Date applies Date.parse, if necessary
        date = date ? new Date(date) : new Date();
        if (isNaN(date)) throw new SyntaxError("invalid date");

        mask = String(dF.masks[mask] || mask || dF.masks["default"]);

        // Allow setting the utc argument via the mask
        if (mask.slice(0, 4) == "UTC:") {
            mask = mask.slice(4);
            utc = true;
        }

        var _ = utc ? "getUTC" : "get",
        d = date[_ + "Date"](),
        D = date[_ + "Day"](),
        m = date[_ + "Month"](),
        y = date[_ + "FullYear"](),
        H = date[_ + "Hours"](),
        M = date[_ + "Minutes"](),
        s = date[_ + "Seconds"](),
        L = date[_ + "Milliseconds"](),
        o = utc ? 0 : date.getTimezoneOffset(),
        flags = {
            d: d,
            dd: pad(d),
            ddd: dF.i18n.dayNames[D],
            dddd: dF.i18n.dayNames[D + 7],
            m: m + 1,
            mm: pad(m + 1),
            mmm: dF.i18n.monthNames[m],
            mmmm: dF.i18n.monthNames[m + 12],
            yy: String(y).slice(2),
            yyyy: y,
            h: H % 12 || 12,
            hh: pad(H % 12 || 12),
            H: H,
            HH: pad(H),
            M: M,
            MM: pad(M),
            s: s,
            ss: pad(s),
            l: pad(L, 3),
            L: pad(L > 99 ? Math.round(L / 10) : L),
            t: H < 12 ? "a" : "p",
            tt: H < 12 ? "am" : "pm",
            T: H < 12 ? "A" : "P",
            TT: H < 12 ? "AM" : "PM",
            Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
            o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
            S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
        };

        return mask.replace(token,
        function($0) {
            return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
        });
    };
} ();

// Some common format strings
dateFormat.masks = {
    "default": "ddd mmm dd yyyy HH:MM:ss",
    shortDate: "m/d/yy",
    mediumDate: "mmm d, yyyy",
    longDate: "mmmm d, yyyy",
    fullDate: "dddd, mmmm d, yyyy",
    shortTime: "h:MM TT",
    mediumTime: "h:MM:ss TT",
    longTime: "h:MM:ss TT Z",
    isoDate: "yyyy-mm-dd",
    isoTime: "HH:MM:ss",
    isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
    isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
    dayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
    monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
};

// For convenience...
Date.prototype.format = function(mask, utc) {
    return dateFormat(this, mask, utc);
};