//Event.observe(window, 'load', function(){
  // 初期化処理
//});

function L(name){return document.getElementsByName(name);}

/* カート内の商品との整合性チェック */
window.ProductsInCartChecker = Class.create();
window.ProductsInCartChecker.prototype = {
  //
  initialize: function(prod_id, qty) {
    this.prod_id = prod_id;
    this.qty = qty;
  },

  //
  check: function() {

    var url = 'ajax_api.php';
    var pars = 'class=Cart_ProductsChecker'
             + '&action=check'
             + '&pid=' + this.prod_id
             + '&qty=' + this.qty
             ;
    // ロード中画像を表示する.
    //this.displayLoadIcons();

    var myAjax = new Ajax.Request(
      url,
      {
        method: 'get',
        parameters: pars,
        asynchronous: false
      }
    );

    var json = eval('(' + myAjax.transport.responseText + ')');
    if (json.res == false) {
        var message = json.err_msg.replace(/:::/, "\n").replace(/&#039;/, "'");
        alert(message);
        return false;
    }

    return true;
  }
};

/* 商品一覧ページ上の処理 */
var ProductsListing = {

  inCart: function(pID, as_special, is_need_nyuka_asking){

    /* カート内の商品との整合性チェック. */
    var cartProdChecker = new ProductsInCartChecker(pID, 1);
    var prod_res = cartProdChecker.check();
    if (prod_res == false) return false;

    /* 入荷商品について確認する. */
    if (is_need_nyuka_asking == true) {
      var res = FormUtil.askAboutNyukaProductWhenInsertingCart();
      if (res == false) return false;
    }

    var url = 'default.php';
    var pars = 'action=buy_now'
            + '&products_id=' + pID
            + '&as_special=' + as_special
            + '&from=list'
            ;
    var myAjax = new Ajax.Request(
      url, 
      {
        method: 'get', 
        parameters: pars, 
        onComplete: this.inCartAjaxHandler
      });
  },

  inCartAjaxHandler: function () {
    alert(JS_IN_CART_COMPLETE);
  }
};

//URL Encode (UTF-8)
function encodeURL(str) {
  var character = '';
  var unicode   = '';
  var string    = '';
  var i         = 0;

  for (i = 0; i < str.length; i++) {
    character = str.charAt(i);
    unicode   = str.charCodeAt(i);

    if (character == ' ') {
      string += '+';
    } else {
      if (unicode == 0x2a || unicode == 0x2d || unicode == 0x2e || unicode == 0x5f || ((unicode >= 0x30) && (unicode <= 0x39)) || ((unicode >= 0x41) && (unicode <= 0x5a)) || ((unicode >= 0x61) && (unicode <= 0x7a))) {
        string = string + character;
      } else {
        if ((unicode >= 0x0) && (unicode <= 0x7f)) {
          character   = '0' + unicode.toString(16);
          string += '%' + character.substr(character.length - 2);
        } else if (unicode > 0x1fffff) {
          string += '%' + (oxf0 + ((unicode & 0x1c0000) >> 18)).toString(16);
          string += '%' + (0x80 + ((unicode & 0x3f000) >> 12)).toString(16);
          string += '%' + (0x80 + ((unicode & 0xfc0) >> 6)).toString(16);
          string += '%' + (0x80 + (unicode & 0x3f)).toString(16);
        } else if (unicode > 0x7ff) {
          string += '%' + (0xe0 + ((unicode & 0xf000) >> 12)).toString(16);
          string += '%' + (0x80 + ((unicode & 0xfc0) >> 6)).toString(16);
          string += '%' + (0x80 + (unicode & 0x3f)).toString(16);
        } else {
          string += '%' + (0xc0 + ((unicode & 0x7c0) >> 6)).toString(16);
          string += '%' + (0x80 + (unicode & 0x3f)).toString(16);
        }
      }
    }
  }

  return string;
}

// フォームに関するユーティリティ関数
var FormUtil = {
  // ラジオボタンで選択されている値を返す
  getRadioValSelected: function (name) {
    var items = document.getElementsByName(name);
    var l = items.length;
    for (var i=0; i<l; i++) {
      if (items[i].checked != '') {
        return items[i].value;
      }
    }

    return false;
  },

  // チェックボックスで選択されている値を返す
  getCheckBoxValSelected: function (name) {
    var items = document.getElementsByName(name);
    var l = items.length;
    for (var i=0; i<l; i++) {
      if (items[i].checked != '') {
        return items[i].value;
      }
    }

    return false;
  },

  // プルダウンメニューを選択する
  selectPulldown: function (id, val) {
    var item = document.getElementById(id);
    var l = item.length;
    for (var i=0; i<l; i++) {
      if (item[i].value == val) {
        item[i].selected = 'selected';
        return true;
      }
    }

    return false;
  },

  /**
   * EmailアドレスのドメインのMXレコード存在チェック
   *
   * @param  string Emailアドレス
   * @return bool
   */
  checkMx: function (mail) {
    // MXレコード存在チェック
    var url = 'ajax_api.php';
    var pars = 'class=Address'
             + '&action=existMx'
             + '&hostname=' + encodeURIComponent(mail)
             ;
    var myAjax = new Ajax.Request(
      url,
      {
        method: 'get',
        parameters: pars,
        asynchronous: false
      }
    );
    var hash = eval('(' + myAjax.transport.responseText + ')');
    return hash.res;
  },

  /**
   * 入荷待ち商品をカートに入れる時の処理
   *
   * @return bool
   */
  askAboutNyukaProductWhenInsertingCart: function() {
    var msg = TEXT_ASK_ABOUT_NYUKA_PRODUCT_WHEN_INSERTING_CART;
    res = confirm(msg);
    if (res == false) return false;
    return true;
  }
};

// DOMイベント関連の関数
var EventUtil = {
  // DOMイベントの登録
  attach: function (elem, event, handler) {
    if(elem.addEventListener) {
      elem.addEventListener(event, handler, false);
    } else {
      elem.attachEvent('on' + event, handler);
    }
  
  },
  // DOMイベントの解除
  detach: function (elem, event, handler) {
    if(elem.removeEventListener)
      elem.removeEventListener(event, handler, false);
    else
      elem.detachEvent('on' + event, handler);
  }
};

// 一般的な処理
var IfgUtil = {
  // メールアドレスのフォーマットチェック
  isValidEmailAddress: function (email) {
    if(email.match(/^[A-Za-z0-9]+[\w\.-]*@[\w\.-]+\.\w{2,}$/)){
      return true;
    }else{
      return false;
    }
  },

  // 電話番号のフォーマットチェック
  isValidTelephone: function (telephone) {
    if(telephone.match(/^[0-9\-]+$/)){
      return true;
    }else{
      return false;
    }
  },

  //---------------------------------------------------------
  // Fade機能
  // - doFadeとともに、FadeIntervalとdoFadeActualも使用する.
  //
  // @param  string targetId 色を付ける要素のID
  // @return void
  //---------------------------------------------------------
  FadeInterval: 600,
  doFadeActual: null,
  doFade: function(targetId) {

    var FadeInterval  = 600;
    var StartFadeAt   = 7;

    // 元の背景色を変数に保持してクロージャ内に束縛する.
    var original_bg_color = document.getElementById(targetId).style.backgroundColor;

    IfgUtil.DoFadeActual = function(targetId, colorId) {
      var FadeSteps = ["", "ff", "ee", "dd", "cc", "bb", "aa", "99"];
      if (colorId >= 1) {
        document.getElementById(targetId).style.backgroundColor = "#ffff" + FadeSteps[colorId];
        // If it's the last color, set it to transparent //'
        if (colorId==1) {
          document.getElementById(targetId).style.backgroundColor = original_bg_color;
        }
        colorId--;

        // Wait a little bit and fade another shade
        setTimeout("IfgUtil.DoFadeActual('"+targetId+"',"+colorId+")", IfgUtil.FadeInterval);
      }
    };

    IfgUtil.DoFadeActual(targetId, StartFadeAt);
  },

  /**
   * Loadアイコンを表示する.
   * - HTTPS_CATALOG_SERVER を事前にglobalに定義しておくこと.
   * - 非表示にする時は、IfgUtil.clearLoadIcon()を使用する.
   * 
   * @param  string id  アイコンを表示する要素ID(この要素の中にアイコン要素が表示される).SPANなど.
   * @return void
   */
  displayLoadIcon: function(id)
  {
    if (!HTTPS_CATALOG_SERVER) {
      var HTTPS_CATALOG_SERVER = '';
    }

    // アイコン用に新規に作成する要素
    var icon_elm_name = id + '_load_icon';
    var icon_elm = $(icon_elm_name);

    // あれば表示する.
    if (icon_elm) {
      icon_elm.style.display = '';
    // なければ追加して表示する.
    } else {
      var s = $(id);
      var elm = document.createElement("img");
      elm.setAttribute("id", icon_elm_name);
      elm.setAttribute("src", HTTPS_CATALOG_SERVER + '/shop/catalog/images/icons/ajax-loader.gif');
      elm.setAttribute("height", "16");
      elm.setAttribute("width", "16");
      elm.setAttribute("alt", "Now Loading");
      s.appendChild(elm);
    }
  },
  clearLoadIcon: function(id)
  {
    var elm = $(id + '_load_icon');
    if (elm) {
      elm.style.display = 'none';
    }
  }
};

// 日付に関する関数
var DateUtil = {
  /**
   * 月を選択した時に、プルダウンメニューの日付選択肢を更新する関数
   * 
   * プルダウンメニューには、以下のようなvalueとtitleが同じものを想定している.
   *  <select name="day">
   *    <option value="1">1</option>
   *    <option value="2">2</option>
   *     : 
   *  </select>
   * 
   * @param  string year_elm_name  年のプルダウンメニュー要素名
   * @param  string month_elm_name 月のプルダウンメニュー要素名
   * @param  string day_elm_name   日のプルダウンメニュー要素名
   * @return void
   */
  updateDate: function (year_elm_name, month_elm_name, day_elm_name) {

    // 選択されている年を取得
    var my_year = document.getElementsByName(year_elm_name)[0].value;

    // 選択されている月を取得
    var my_month = document.getElementsByName(month_elm_name)[0].value;

    // 日付プルダウンメニューと、選択されているインデックスを取得
    var my_days = document.getElementsByName(day_elm_name)[0];
    var my_day_index = my_days.selectedIndex;

    // その月の最後の日付を取得
    var last_day = DateUtil.getLastDay(my_year, my_month);

    // day_elm_name に、各日付のoption要素を追加する.
    // 元々選択されている日付があれば、それを選択状態にする.
    for (var i = 0; i < my_days.length; i++) { my_days.options[i] = null; }
    for (var i = 1; i <= last_day; i++) {
      my_days.options[i-1] = new Option(i, i);
    }
    if (my_day_index < my_days.length) {
      my_days.selectedIndex = my_day_index;
    }
  },

  /**
   * 月の最後の日付を返す.
   * 
   * @param  int year   年
   * @param  int month  月
   * @return int
   */
  getLastDay: function (year, month) {
    var last_date = new Date(year, month, 0);
    return last_date.getDate();
  },

  /**
   * 指定された期間内の月リストを更新する.
   * 
   * @param  string year_elm_name  年のプルダウンメニュー要素名
   * @param  string month_elm_name 月のプルダウンメニュー要素名
   * @param  string date_start_str 期間のはじめの日付文字列 eg. '20080316'
   * @param  string range_elm_name 期間を保持する変数名(単位は日)
   */
  updateMonthForYear: function(year_elm_name, month_elm_name, date_start_str, range_elm_name){
    // 選択されている年を取得
    var my_year = document.getElementsByName(year_elm_name)[0].value;

    // 月のプルダウンメニューを取得
    var elm_month = document.getElementsByName(month_elm_name)[0];
    var elm_month_index = elm_month.selectedIndex;

    // 期間を取得
    var date_range = eval(range_elm_name);

    // 期間開始日
    var y  = parseInt(date_start_str.substr(0, 4));
    var m  = parseInt(date_start_str.substr(4, 2));
    var d  = parseInt(date_start_str.substr(6, 2));
    var date_tmp = new Date(y, m-1, d);
    var day_tmp = date_tmp.getDate();

    // 期間内の日毎に処理
    var months = new Array();
    for (var i=0; i<date_range; i++){
      date_tmp.setDate(date_tmp.getDate() + 1);
      var month = date_tmp.getMonth() + 1;
      // 年が year と一致 && months にまだ存在しない 場合
      if ((date_tmp.getYear()+1900) == my_year && !ArrayUtil.hasValue(months, month)) {
        // months に追加する.
        months[months.length] = month;
      }
    }
    //months.sort();

    // month_elm_name 要素の選択肢を更新する.
    for (var cnt = elm_month.length; cnt >= 0 ; cnt--) { elm_month.options[cnt] = null; }
    for (var i = 0, cnt = months.length; i < cnt; i++) {
      elm_month.options[i] = new Option(months[i], months[i]);
    }
    if (elm_month_index < elm_month.length) {
      elm_month.selectedIndex = 0;
    }
  },

  /**
   * 指定された期間内の日にちリストを更新する.
   * 
   * @param  string year_elm_name  年のプルダウンメニュー要素名
   * @param  string month_elm_name 月のプルダウンメニュー要素名
   * @param  string day_elm_name   日のプルダウンメニュー要素名
   * @param  string date_start     期間のはじめの日付文字列 eg. '20080316'
   * @param  string range_elm_name 期間を保持する変数名(単位は日)
   */
  updateDayForYear: function(year_elm_name, month_elm_name, day_elm_name, date_start_str, range_elm_name){
    // 選択されている年を取得
    var my_year = document.getElementsByName(year_elm_name)[0].value;

    // 選択されている月を取得
    var my_month = document.getElementsByName(month_elm_name)[0].value;

    // 日のプルダウンメニューを取得
    var elm_day = document.getElementsByName(day_elm_name)[0];
    var elm_day_index = elm_day.selectedIndex;

    // 期間を取得
    var date_range = eval(range_elm_name);

    // 期間開始日
    var y  = parseInt(date_start_str.substr(0, 4));
    var m  = parseInt(date_start_str.substr(4, 2));
    var d  = parseInt(date_start_str.substr(6, 2));
    var date_tmp = new Date(y, m-1, d);
    var day_tmp = date_tmp.getDate();

    // 期間内の日毎に処理
    var days = new Array();
    for (var i=0; i<date_range; i++){
      date_tmp.setDate(date_tmp.getDate() + 1);
      var day   = date_tmp.getDate();
      var month = date_tmp.getMonth() + 1;
      // 年が year と一致 && 月が month と一致 && days にまだ存在しない 場合
      if ((date_tmp.getYear()+1900) == my_year && month == my_month && 
          !ArrayUtil.hasValue(days, day)) {
        // months に追加する.
        days[days.length] = day;
      }
    }
    //days.sort();

    // day_elm_name 要素の選択肢を更新する.
    for (var cnt = elm_day.length; cnt >= 0; cnt--) { elm_day.options[cnt] = null; }
    for (var i = 0, cnt = days.length; i < cnt; i++) {
      elm_day.options[i] = new Option(days[i], days[i]);
    }
    if (elm_day_index < elm_day.length) {
      elm_day.selectedIndex = 0;
    }
  }
};

var ArrayUtil = {
  /**
   * オブジェクトが指定した値を持っているかを返す.
   * 
   * @param  object o
   * @param  val    mixed
   * @param  int    type  1: ==で評価する / 2: === で評価する
   * @return bool
   */
  hasValue: function(o, val, type){
    if (!type) type = 2;
    for(var prop in o){
      if (type === 1) {
        if (o[prop] == val) return true;
      } else {
        if (o[prop] === val) return true;
      }
    }
    return false;
  }
};

// 位置に関する関数
var PositionUtil = {
  /**
   * 要素のスタイルプロパティ値を返す.
   * 
   * @param object elm       目的の要素
   * @param string ieCssProp "paddingLeft" の形式
   */
  getElementsStyleValue: function(elm, ieCssProp){
    if (elm.currentStyle) return elm.currentStyle[ieCssProp];

    var cssProp = ieCssProp.replace( /([A-Z])/g, "-$1" ).toLowerCase(); // 'padding-left' になる.
    return document.defaultView.getComputedStyle(elm, null).getPropertyValue(cssProp);
   }
};
