/**
 * Zer0Mem0Ry - Hatebuコメント取得スクリプト
 * Copyright (c) 2006 suVene<suvene@gmail.com>
 * @version 1.1.0
 * history
 * ver. 1.0.0 2006/08/22
 *  ・ 初版
 * ver. 1.1.0 2006/08/23
 *  ・ Mozila対応
 *  ・ proxy変更対応
 *  ・ 見た目整形
 *
 * freely distributable under the terms of an MIT-style license.
 * http://www.opensource.jp/licenses/mit-license.html
 */

/** global variable */
if (Zer0 == undefined) {
  var Zer0 = {
    _DEBUG_: false
  };
}
var Zer0_hatebu_comment = 'hatebuComment';
(function() {

/** define */
var proxy = 'http://app.drk7.jp/xml2json/';
var hatebu_exists_api = 'http://d.hatena.ne.jp/exist?mode=xml&url=';
var hatebu_comment_rss = 'http://b.hatena.ne.jp/entry/rss/';
// css class
var Zer0_css_hatebu_box = 'zero_hatebu_box';
var Zer0_css_hatebu_title = 'zero_hatebu_title';
var Zer0_css_hatebu_body = 'zero_hatebu_body';
var Zer0_css_hatebu_dtm = 'zero_hatebu_dtm';
var Zer0_css_hatebu_img = 'zero_hatebu_img';
var Zer0_css_hatebu_name = 'zero_hatebu_name';
var Zer0_css_hatebu_tag = 'zero_hatebu_tag';
var Zer0_css_hatebu_comment = 'zero_hatebu_comment';

var element; // target

/** Hatena Object */
Zer0.Hatena = {
  xml2json: function(varName, url) {
    var url = (proxy + 'var=' + varName + '&url=' + escape(url));
    var script = document.createElement('script');
    script.charset = 'utf-8';
    script.src = url;
    // Zer0.Debuger.debug('Zer0.Hatena.xml2json', url);
    document.body.appendChild(script);
    return true;
  }
}

/** Hatebu Object */
Zer0.HatebC = {
  // window load
  load: function() {
    try {
      if (Zer0._DEBUG_) { Zer0.Debuger.initialize(); }
      element = document.getElementById(Zer0_hatebu_comment);
      if (!element) { return; }
      if (element.getAttribute('proxy')) { proxy = element.getAttribute('proxy'); }
      // call exist API
      Zer0.Hatena.xml2json('Zer0.HatebC.exist', hatebu_exists_api + element.getAttribute('url'));
    } catch(e) { errHandler('Zer0.HatebC.load', e) }
  },
  // window unload
  unload: function() {
    try {
    } catch(e) { errHandler('Zer0.HatebC.unload', e); }
  },
  // exist API callback
  exist: {
    onload: function(data) {
      try {
        // is bookmarked
        eval(data.count.bookmark.content);

        // get Hatebu Comment
        Zer0.Hatena.xml2json('Zer0.HatebC', hatebu_comment_rss + element.getAttribute('url'));
      } catch(e) { /* errHandler('Hatebu#exist#onload', e); */ }
    }
  },
  // Hatebu Comment callback(View)
  onload: function(data) {
    try {
      var title = element.getAttribute('title');
      if (!title) { title = 'Hatena Bookmark'; }
      var res = '<div class="' + Zer0_css_hatebu_box + '">'
               + '<div class="' + Zer0_css_hatebu_title + '">' + title + '</div>'
               + '<ul class="' + Zer0_css_hatebu_body + '">';
      var users = _toArray(data.item);
      for (i in users) {
//      for (var i = users.length - 1; i >= 0; i--) { // order by asc
        var user = users[i];

        var userName = user['title'];
        var profileImgURL = 'http://www.hatena.ne.jp/users/' + userName.substring(0, 2) + '/' + userName + '/profile_s.gif';
        var dateTime = user['dc:date'];
        dateTime = dateTime.split('T').join(' ').split('+')[0].replace(/-/g, '/').substring(0, 16);
        var tags = _toArray(user['dc:subject']);
        var tag = '';
        for (j in tags) {
          tag += '[' + _escapeHTML(tags[j]) + '], ';
        }
        tag = tag.replace(/, $/, '');

        var comment = typeof user['description'] == 'string' ? user['description'] : '';
        res += '<li>'
            + '<span class="' + Zer0_css_hatebu_dtm + '">' + dateTime + '</span>&nbsp;'
            + '<a href="http://b.hatena.ne.jp/' + userName + '/">'
              + '<img class="' + Zer0_css_hatebu_img + '" src="' + profileImgURL
                  + '" alt="' + userName + '" title="' + userName + '" border="0" width="16" height="16" />&nbsp;'
            + '<span class="' + Zer0_css_hatebu_name + '">' + userName + '</span></a>&nbsp;'
            + '<span class="' + Zer0_css_hatebu_tag + '">' + tag + '</span>&nbsp;'
            + '<span class="' + Zer0_css_hatebu_comment + '">' + _escapeHTML(comment) + '</span>'
            + '</li>';
      }
      element.innerHTML = res + '</ul></div>';
    } catch(e) { errHandler('Zer0.HatebC.onload', e); }
  }
}

/** Zer0 Utility */
Zer0.Util = {
  nvl: function(obj, defaultValue) {
    if (defaultValue == null || defaultValue == undefined) {
      defaultValue  = '';
    }
    if (obj == undefined) return defaultValue;
    if (obj == null) return defaultValue;
    return obj;
  },
  /**
   * String Utility
   */
  String: {
    /**
     * padding
     * @param string target
     * @param int length
     * @param string [fillstr](' ')
     * @param boolean [lpad](true)
     */
    pad: function(str, len, fillstr, lpad) {
      var ret = String(str);
      len = Zer0.Util.nvl(len, 1);
      fillstr = Zer0.Util.nvl(fillstr, ' ');
      lpad = Boolean(Zer0.Util.nvl(len, true));
      if (lpad) {
        while (ret.length < len) {
           ret = fillstr + ret;
        }
      } else {
        while (ret.length < len) {
           ret = ret + fillstr;
        }
      }
      return ret;
    }
  },

  /**
   * Number Utility
   */
  Number: {
  },

  /**
   * Date Utility
   */
  Date: {
    /**
     * get now
     * @param String format
     */
    getToday: function(format) {
      format = Zer0.Util.nvl(format, 'yyyy/MM/dd');
      return this.format(new Date, format);
    },
    getNow: function(format) {
      format = Zer0.Util.nvl(format, 'yyyy/MM/dd hh24:mi:ss');
      return this.format(new Date, format);
    },

    /**
     * date format
     * @param date
     * @param [format] default yyyy/MM/dd hh24:mi:ss
     */
    format: function(date, format) {

      var ret = String(Zer0.Util.nvl(format, 'yyyy/MM/dd hh24:mi:ss'));

      var y = date.getYear();
      if (y < 2000) {
        y += 1900;
      }
      var y2 = y - (Math.floor(y / 100) * 100 );
      var m = date.getMonth() + 1;
      var d = date.getDate();
      var hh24 = date.getHours();
      var h = hh24 > 12 ? hh24 - 12 : hh24;
      var i = date.getMinutes();
      var s = date.getSeconds();

      ret = ret.replace('yyyy', y).replace('yy', y2)
               .replace('MM', Zer0.Util.String.pad(m, 2, '0')).replace('M', m)
               .replace('dd', Zer0.Util.String.pad(d, 2, '0')).replace('d', d)
               .replace('hh24', hh24).replace('hh', Zer0.Util.String.pad(h, 2, '0')).replace('h', h)
               .replace('mi', Zer0.Util.String.pad(i, 2, '0')).replace('m', i)
               .replace('ss', Zer0.Util.String.pad(s, 2, '0')).replace('s', s);
      return ret;
    }
  }
}


// attach event
if (window.addEventListener) {
  window.addEventListener('load', Zer0.HatebC.load, false);
  window.addEventListener('unload', Zer0.HatebC.unload, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', Zer0.HatebC.load);
  window.attachEvent('onunload', Zer0.HatebC.unload);
}

function _bind(f, thisObj) {
  var _self = thisObj;
  return function() {
    try {
      return f.apply(thisObj, arguments);
    } catch(e) {
      errHandler('bind', e, f);
    }
  }
}

function _toArray(obj) {
  if (!obj) {
    return [];
  } else if (obj instanceof Array) {
    return obj;
  } else if (obj.toArray) {
    return obj.toArray();
  } else {
    var ret = [];
    ret.push(obj);
    return ret;
  }
}

function _escapeHTML(str) {
  str += '';
  return str.replace(/[&"<>]/g, function(c) {
    return {
      '&': '&amp;',
      '"': '&quot;',
      '<': '&lt;',
      '>': '&gt;'
    }[c];
  });
}

function errHandler(msg, e, description) {
  alert('[ERROR]' + msg + '\n' + e.message + '\n' + (description == undefined ? '' : description));
}

})();
