var GCalHolidays = {
    userIds: [
        "japanese__ja@holiday.calendar.google.com"
    ],

    maxResults: 31,

    visibility: "public",

    projection: "full-noattendees"
};
GCalHolidays.get = function(callback, year, month) {
    var padZero = function(value) { return ("0" + value).slice(-2); };
    var y = year || new Date().getFullYear();
    var start = [y, padZero(month || 1), "01"].join("-");
    var m = month || 12;
    var end = [y, padZero(m), padZero(new Date(y, m, 0).getDate())].join("-");

    this._caches = (this._caches || {});
    this._userCallback = callback;

    for (var i = 0, len = this.userIds.length; i < len; i++) {
        var cache = this._caches[i + ":" + start + ".." + end];
        if (cache) {
            callback(cache, i);
            continue;
        }

        var url = location.protocol + "//www.google.com/calendar/feeds/";
        url += encodeURIComponent(this.userIds[i]) + "/";
        url += this.visibility + "/" + this.projection;
        url += "?alt=json-in-script&callback=GCalHolidays.decode";
        url += "&max-results=" + this.maxResults;
        url += "&start-min=" + start + "&start-max=" + end;

        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = url;
        script.charset = "UTF-8";
        document.body.appendChild(script);
    }
};
GCalHolidays.decode = function(gdata) {
    var days = GCalHolidays._entries2days(gdata.feed.entry);
    var href = gdata.feed.link[3].href;

    var userId = decodeURIComponent(href.split("/")[5]);
    var index;
    for (var i = 0, len = this.userIds.length; i < len; i++) {
        if (this.userIds[i] == userId) {
            index = i;
            break;
        }
    }

    var range = href.match(/\d{4}-\d{2}-\d{2}/g);
    this._caches[index + ":" + range[0] + ".." + range[1]] = days;

    this._userCallback(days, index);
};


GCalHolidays._entries2days = function(entries) {
    if (!entries) {
        return [];
    }

    entries.sort(function(a, b) {
        return (a.gd$when[0].startTime > b.gd$when[0].startTime) ? 1 : -1;
    });

    var days = [];
    for (var i = 0, len = entries.length; i < len; i++) {
        var ymd = entries[i].gd$when[0].startTime.split("T")[0].split("-");
        var title = entries[i].title.$t;
        days[i] = { year: ymd[0] * 1, month: ymd[1] * 1, date: ymd[2] * 1, title: title };
    }
    return days;
};
