/*
 * BeatJam の定数
 */
var BJConst = {

  /*
   * WMA 非対応の製品名
   */
  WMAexcludeProducts:{
    'MPOMG103DD':true,
    'MPOMG100TSB':true,
    'MPOMG101TSB':true,
    'MPOMG102TSB':true,
    'MPOMG103TSB':true,
    'MPOMG104TSB':true
  },

  /*
   * BeatJam のインストール状態
   */
  BjInstallState:{
    'unknown':-1,
    'no_ocx':0,
    'latest_ocx':1,
    'older_ocx':2,
    'no_bj':3,
    'latest':4,
    'older':5,
    'latest_le':6,
    'older_le':7
  },

  /*
   * 対応バージョン
   */
  Versions:{
    'playlog':2030100,
    'bjprotocol':2020900,
    'ongen':2040100,
    'libsync':2040100,
    'latest':2030300,
    'latest_le':2030300,
    'latest_ocx':1010100
  },

  ocxId:'BJVERCHK',

  /*
   * BeatJam 判別用 ActiveX の OBJECT タグ表示用文字列
   */
  ocxObjectStr:'<object ' 
    + 'classid="clsid:84ACC484-D8CE-40CC-8BFA-C8458F94ABB6" '
    + 'id="BJVERCHK" '
    + 'style="visibility:hidden;">'
    + '</object>',

  /*
   * BeatJam 判別用 ActiveX 最新版の OBJECT タグ表示用文字列
   */
  latestOcxObjectStr:'<object '
    + 'classid="clsid:84ACC484-D8CE-40CC-8BFA-C8458F94ABB6" '
    + 'id="BJVERCHK" '
    + 'CODEBASE="http://beatjam.jp/app/images/bjchecker/BJVerChkWeb.ocx'
    + '#Version=1,1,1,0"'
    + 'style="visibility:hidden;">'
    + '</object>'

}

/*
 * ActiveX を用いるユーティリティ
 * IE 系ブラウザのときのみ利用可能であることに注意．
 */
var BJOcxUtil = {
  BjInfo:{},
  bjverchk:null,
  
  /*
   * <機能>
   *   BeatJam がインストールされているかどうか判別する．
   * <戻り値>
   *   true/false
   */
  isBjInstalled:function() {
    return this.getBjInfo()['bj_installed'];
  },

  /*
   * <機能>
   *   BeatJam LE がインストールされているかどうか判別する．
   * <戻り値>
   *   true/false
   */
  isBjleInstalled:function() {
    return this.getBjInfo()['isle'];
  },

  /*
   * <機能>
   *   PLAYLOG 対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isPLAYLOGCapable:function() {
    if (this.getBjVersionNum() >= BJConst.Versions['playlog']) {
      return true;
    } else {
      return false;
    }
  },

  /*
   * <機能>
   *   WMA 対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isWMACapable:function() {
    if (BJConst.WMAexcludeProducts[this.getBjProductName()] != undefined) {
      return false;
    } else {
      return this.isPLAYLOGCapable();
    }
  },

  /*
   * <機能>
   *   beatjam プロトコル対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isBeatjamProtocolCapable:function() {
    if (this.getBjVersionNum() >= BJConst.Versions['bjprotocol']) {
      return true;
    } else {
      return false;
    }
  },

  /*
   * <機能>
   *   ブラウザ種別と beatjam プロトコル機能有無の組み合わせに従って URL の
   *   プロトコルを変換する．
   *   IE からのアクセスで BJ プロトコル対応 BJ を起動させたいときに使用する．
   *
   *   beatjam://    ○             ×
   *   -------------+--------------+----------------------
   *   内蔵ブラウザ  http://        http://
   *   通常ブラウザ  beatjam://     http://
   *
   * <引数>
   *   変換元URL
   * <戻り値>
   *   変換後URL
   */
  replaceProtocol:function(url) {
    if (!BJBrowserUtil.isBeatJam() && this.isBeatjamProtocolCapable()) {
      url = url.replace(/^https:\/\//, 'beatjams://');
      url = url.replace(/^http:\/\//, 'beatjam://');
    }
    return url;
  },

  /*
   * <機能>
   *   製品名を取得する．
   * <戻り値>
   *   製品名/undefined(BJ未導入およびブラウザが非IE 時)
   */
  getBjProductName:function() {
    return this.getBjInfo()['productname'];
  },

  /*
   * <機能>
   *   バージョン番号を文字列型で取得する．
   * <戻り値>
   *   バージョン番号/'-1'(BJ未導入およびブラウザが非IE 時)
   */
  getBjVersionStr:function() {
    return this.getBjInfo()['bj_ver_str'];
  },
  
  /*
   * <機能>
   *   バージョン番号を数値型で取得する．
   * <戻り値>
   *   バージョン番号/-1(BJ未導入およびブラウザが非IE 時)
   */
  getBjVersionNum:function() {
    return this.getBjInfo()['bj_ver_num'];
  },

  /*
   * <機能>
   *   BeatJam の導入状態を取得する．
   * <戻り値>
   *   BJConst.BjInstallState['unknonw']    判別不可能．
   *   BJConst.BjInstallState['no_ocx']     ActiveX が導入されていない．
   *   BJConst.BjInstallState['latest_ocx'] 最新の ActiveX が導入済み．
   *   BJConst.BjInstallState['older_ocx']  最新ではない ActiveX が導入済み．
   *
   */
  getOcxInstallState:function() {
    if (BJBrowserUtil.isIE()) {
      try {
        var ocx_ver_str = this.getOcx().GetObjectVersion();
        // ActiveX は導入されている．
        var v = ocx_ver_str.split('.');
        var ver = v[0] * 1000000 + v[1] * 10000 + v[2] * 100 + v[3] * 1;
        if (ver >= BJConst.Versions['latest_ocx']) {
          return BJConst.BjInstallState['latest_ocx'];
        } else {
          return BJConst.BjInstallState['older_ocx'];
        }
      } catch (e) {
        // ActiveX は導入されていない．
        return BJConst.BjInstallState['no_ocx'];
      }
    } else {
      return BJConst.BjInstallState['unknown'];
    }
  },

  /*
   * <機能>
   *   BeatJam の導入状態を取得する．
   * <戻り値>
   *   BJConst.BjInstallState['unknonw']    判別不可能．
   *   BJConst.BjInstallState['no_ocx']     BJ 判定 ActiveX が導入されていない．
   *   BJConst.BjInstallState['older_ocx']  最新ではない ActiveX が導入済み．
   *   BJConst.BjInstallState['no_bj']      BeatJam が導入されていない．
   *   BJConst.BjInstallState['latest']     最新の BeatJam が導入済み．
   *   BJConst.BjInstallState['older']      最新ではない BeatJam が導入済み．
   *   BJConst.BjInstallState['latest_le']  最新の BeatJam LE が導入済み．
   *   BJConst.BjInstallState['older_le']   最新ではない BeatJam LE が導入済み．
   *
   */
  getBjInstallState:function() {
    if (BJBrowserUtil.isIE()) {
      // IE 系ブラウザ
      var ocx_state = this.getOcxInstallState();
      if (ocx_state != BJConst.BjInstallState['latest_ocx']) {
        return ocx_state;
      }
      if (this.isBjInstalled()) {
        // BJ が導入済み
        if (this.isBjleInstalled()) {
          // LE である
          if (this.getBjVersionNum() >= BJConst.Versions['latest_le']) {
            // 最新版である
            return BJConst.BjInstallState['latest_le'];
          } else {
            // 最新版でない
            return BJConst.BjInstallState['older_le'];
          }
        } else {
          // SE である
          if (this.getBjVersionNum() >= BJConst.Versions['latest']) {
            // 最新版である
            return BJConst.BjInstallState['latest'];
          } else {
            // 最新版でない
            return BJConst.BjInstallState['older'];
          }
        }
      } else {
        // BJ が入っていない
        return BJConst.BjInstallState['no_bj'];
      }
    } else {
      // 非 IE 系ブラウザ
      return BJConst.BjInstallState['unknown'];
    }
  },

  getDummyDiv:function() {
    var d = document.getElementById('ocx_div');
    if (d == null) {
      d = document.createElement('div');
      d.setAttribute('id', 'ocx_div');
      document.body.appendChild(d);
    }
    return d;
  },

  /*
   * <機能>
   *   BeatJam 判別用 ActiveX の OBJECT タグを表示しオブジェクトを生成する．
   * <戻り値>
   *   ActiveX オブジェクト
   */
  getOcx:function() {
    var obj = document.getElementById(BJConst.ocxId);
    if (obj == null) {
      this.getDummyDiv().innerHTML = BJConst.ocxObjectStr;
      obj = document.getElementById(BJConst.ocxId);
    }
    return obj;
  },

  /*
   * <機能>
   *   BeatJam 判別用 ActiveX 最新版の OBJECT タグを表示する．
   * <戻り値>
   *   なし．
   */
  putLatestOcx:function() {
    var obj = document.getElementById(BJConst.ocxId);
    if (obj != null) {
      obj.parentNode.removeChild(obj);
    }
    this.getDummyDiv().innerHTML = BJConst.latestOcxObjectStr;
    obj = document.getElementById(BJConst.ocxId);
    return obj;
  },

  getBjInfo:function() {
    if (this.BjInfo['bj_installed'] == undefined) {
      try {
        var ocx = this.getOcx();
        var ocx_ver_str = ocx.GetObjectVersion();
        this.BjInfo['ocx_ver_str'] = ocx_ver_str;
        var ov = ocx_ver_str.split('.');
        this.BjInfo['ocx_ver_num'] = 
          ov[0] * 1000000 + ov[1] * 10000 + ov[2] * 100 + ov[3] * 1;
        var bj_ver_str = ocx.GetBJVersion();
        if (bj_ver_str != "") {
          // BJ が導入済み．
          this.BjInfo['bj_installed'] = true;
          this.BjInfo['bj_ver_str'] = bj_ver_str;
          var v = bj_ver_str.split('.');
          this.BjInfo['bj_ver_num'] =
            v[0] * 1000000 + v[1] * 10000 + v[2] * 100 + v[3] * 1;
          try {
            var s = ocx.GetBJSpec().split('-');
            this.BjInfo['productname'] = s[1];
            if (s[2] == '01' && (s[3].substr(s[3].length - 3, 1) % 2) == 0) {
              this.BjInfo['isle'] = true;
            } else {
              this.BjInfo['isle'] = false;
            }
          } catch (e2) {
            this.BjInfo['isle'] = false;
          }
          return this.BjInfo;
        } else {
          // ActiveX は導入されているが BJ が入っていない．
        }
      } catch(e) {
        // IE 系以外のブラウザまたは ActiveX が未導入．
      }
      this.BjInfo['bj_installed'] = false;
      this.BjInfo['ocx_ver_str'] = '-1';
      this.BjInfo['ocx_ver_num'] = -1;
      this.BjInfo['bj_ver_str'] = '-1';
      this.BjInfo['bj_ver_num'] = -1;
      this.BjInfo['isle'] = false;
    }
    return this.BjInfo;
  }
}

/*
 * ブラウザ用のユーティリティ
 */
var BJBrowserUtil = {

  /*
   * <機能>
   *   ブラウザが IE系 がどうか判別する．
   * <戻り値>
   *   true/false
   */
  isIE:function() {
    if (window.ActiveXObject) {
      return true;
    } else {
      return false;
    }
  },

  /*
   * <機能>
   *   ブラウザが BeatJam の内蔵ブラウザかどうか判別する．
   * <戻り値>
   *   true/falase
   */
  isBeatJam:function() {
    try {
      window.external.JS_GetAppName();
      return true;
    } catch (e) {
      return false;
    }
  },

  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときにライブラリアップロード機能対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isLibSyncCapable:function() {
    if (this.isBeatJam()) {
      if (this.getBjVersionNum() >= BJConst.Versions['libsync']) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  },

  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときに Ongen 対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isOngenCapable:function() {
    if (this.isBeatJam()) {
      if (this.getBjVersionNum() >= BJConst.Versions['ongen']) {
        return true;
      } else {
        return false;
      }
    } else {
      return true;
    }
  },

  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときに PLAYLOG 対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isPLAYLOGCapable:function() {
    if (this.isBeatJam()) {
      if (this.getBjVersionNum() >= BJConst.Versions['playlog']) {
        return true;
      } else {
        return false;
      }
    } else {
      return true;
    }
  },

  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときに WMA 対応版の BeatJam かどうか判別する．
   * <戻り値>
   *   true/false
   */
  isWMACapable:function() {
    if (BJConst.WMAexcludeProducts[this.getBjProductName()]) {
      return false;
    } else {
      return this.isPLAYLOGCapable();
    }
  },
  
  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときに製品名を取得する．
   * <戻り値>
   *   製品名/undefined(BeatJam 内蔵ブラウザ以外のとき)
   */
  getBjProductName:function() {
    return this.getCookies()['w'];
  },

  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときにバージョン番号を文字列型で取得する．
   * <戻り値>
   *   バージョン番号/"-1"(BeatJam 内蔵ブラウザ以外のとき)
   */
  getBjVersionStr:function() {
    if (navigator.userAgent.match(/BeatJam *([0-9\.]*)/)) {
      return RegExp.$1;
    } else {
      return '-1';
    }
  },
  
  /*
   * <機能>
   *   BeatJam 内蔵ブラウザのときにバージョン番号を数値型で取得する．
   * <戻り値>
   *   バージョン番号/-1(BeatJam 内蔵ブラウザ以外のとき)
   */
  getBjVersionNum:function() {
    var bj_ver_str = this.getBjVersionStr();
    if (bj_ver_str != '-1') {
      var v = bj_ver_str.split('.');
      return v[0] * 1000000 + v[1] * 10000 + v[2] * 100 + v[3] * 1;
    } else {
      return -1;
    }
  },
  
  getCookies:function() {
    var value = document.cookie;
    var keys = value.split('; ');
    var cookies = {};
    for (var i = 0; i < keys.length; i++) {
      if (keys[i].match(/(.*)=(.*)/)) {
        cookies[RegExp.$1] = RegExp.$2;
      } else {
        cookies[keys[i]] = '';
      }
    }
    return cookies;
  }

}
