/*
 * Copyright(C) clickcom.co.jp
 */

function _voidEnterSubmit(e) {
  if (e.keyCode == Event.KEY_RETURN) {
    Event.stop(e);
  }
}

/* form utilities. */
var FormUtils = {};
FormUtils.newInputElement = function(sType, o) {
  return new Element("input", Object.extend(o, {
    type : sType
  }));
};

FormUtils.newHidden = function(o) {
  return FormUtils.newInputElement("hidden", o);
};

FormUtils.newText = function(o) {
  return FormUtils.newInputElement("text", o);
};

FormUtils.newSubmit = function(o) {
  return FormUtils.newInputElement("submit", o);
};

FormUtils.newReset = function(o) {
  return FormUtils.newInputElement("reset", o);
};

FormUtils.newButton = function(o) {
  return FormUtils.newInputElement("button", o);
};
FormUtils.newRadio = function(o) {
  return FormUtils.newInputElement("radio", o);
};
FormUtils.newCheckbox = function(o) {
  return FormUtils.newInputElement("checkbox", o);
};
FormUtils.newSelect = function(o) {
  return new Element("select", o);
};
FormUtils.newTextArea = function(o) {
  return new Element("textarea", o);
};

FormUtils.newLabel = function(sText, sFor) {
  return new Element("label", {
    "for" : sFor
  }).update(sText);
};

/**
 * ページ初期化
 */
document.observe("dom:loaded", function(o) {
  /* ダミーのテキストエリアを挿入 */
  // $$("FORM[id!=searchForm][id!=authInfo]").each(function(o) {
  // var oDummyText = new Element("input", { type : "text", style : "display:
  // none;" });
  // o.appendChild(oDummyText);
  // });
  dojo.query("FORM[id!=searchForm][id!=ch_searchForm][id!=authInfo]").forEach(function(o) {
    dojo.create("input", {
      type : "text",
      style : "display: none;"
    }, o);
  });
  /* INPUT type="text" での Enterキータイプでサブミットさせない。 */
  $$("FORM[id!=searchForm][id!=ch_searchForm] INPUT[type=text]").each(function(o) {
    o.observe("keypress", _voidEnterSubmit);
  });
});

/**
 * 子要素の追加/削除ボタンを追加する。
 * 
 * @param sContainerId
 */
function prepareChildrenOperations(sContainerId, sCollectionName) {
  if (!$(sContainerId)) {
    alert("undefined " + sContainerId);
    return false;
  }
  var oOperations = new Element("div", {
    "class" : "operations"
  });
  var sBtnAdd = "btn-add-" + sContainerId;
  var sBtnDel = "btn-del-" + sContainerId;

  oOperations.appendChild(new Element("button", {
    id : sBtnAdd
  }).update("追加"));
  oOperations.appendChild(new Element("button", {
    id : sBtnDel
  }).update("削除"));
  $(sContainerId).insert({
    after : oOperations
  });

  $(sBtnAdd).observe("click", function(o) {
    Event.stop(o);
    /* add near school. */
    var f = o.element().form;
    var h = new Element("input", {
      name : "addChild",
      type : "hidden",
      value : sCollectionName
    });
    $(sContainerId).appendChild(h);
    /* 非同期で更新 */
    new Ajax.Updater(sContainerId, f.action, {
      parameters : Form.serialize(f),
      evalScripts : true
    });
  });
  $(sBtnDel).observe("click", function(o) {
    Event.stop(o);
    var f = o.element().form;
    var h = new Element("input", {
      name : "deleteChildren",
      type : "hidden",
      value : sCollectionName
    });
    $(sContainerId).appendChild(h);
    /* 非同期で更新 */
    new Ajax.Updater(sContainerId, f.action, {
      parameters : Form.serialize(f),
      evalScripts : true
    });
  });
}
/*
 * var GoogleMap = Class.create(); GoogleMap.prototype = { initialize:
 * function(sName, oOpts){ this.name = sName; this.options = oOpts; this.markers =
 * [];
 * 
 * this.map = new google.maps.Map(this.name, this.options);
 * 
 * this.geocoder = new google.maps.Geocoder(); }, getMarkers: function(){ return
 * this.markers; }, getMap: function(){ return this.map; },
 * addNewMarkerByLatLng: function(oLatLng){ var marker = new
 * google.maps.Marker({position: oLatLng, map: this.map});
 * this.addMarker(marker); }, addMarker: function(oMarker){
 * this.markers.push(oMarker); this.map.panTo(oMarker.getPosition()); },
 * firstMarker: function(oMarker){ this.markers.first(); }, lastMarker:
 * function(oMarker){ this.markers.last(); }, getLatLngByAddress:
 * function(sAddress){ var latLng; this.geocoder.geocode({address: sAddress},
 * function(results, status){ if(status == google.maps.GeocoderStatus.OK){
 * latLng = results.first.geometry.location; }else{
 * alert("ジオコードは次の理由のため照会できませんでした。\n理由: " + status); } }); return latLng; },
 * addListener: function(sType, fnHandler){
 * google.maps.event.addListener(this.map, sType, fnHandler); }, trigger:
 * function(sType){ google.maps.event.trigger(this.map, sType); } };
 */

/**
 * 
 */
function japanizedCalendar(oCal) {
  /* FIXME 汎用的な設定は外部へ */
  // 年月日の並び順
  oCal.cfg.setProperty("MDY_YEAR_POSITION", 1);
  oCal.cfg.setProperty("MDY_MONTH_POSITION", 2);
  oCal.cfg.setProperty("MDY_DAY_POSITION", 3);

  // 年月の並び順
  oCal.cfg.setProperty("MY_YEAR_POSITION", 1);
  oCal.cfg.setProperty("MY_MONTH_POSITION", 2);

  // 月
  oCal.cfg.setProperty("MONTHS_SHORT", [ "1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708" ]);
  oCal.cfg.setProperty("MONTHS_LONG", [ "1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708" ]);
  // 曜日
  oCal.cfg.setProperty("WEEKDAYS_1CHAR", [ "\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F" ]);
  oCal.cfg.setProperty("WEEKDAYS_SHORT", [ "\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F" ]);
  oCal.cfg.setProperty("WEEKDAYS_MEDIUM", [ "\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F" ]);
  oCal.cfg.setProperty("WEEKDAYS_LONG", [ "\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F" ]);
  // ラベルの年月並び順
  oCal.cfg.setProperty("MY_LABEL_YEAR_POSITION", 1);
  oCal.cfg.setProperty("MY_LABEL_MONTH_POSITION", 2);
  // ラベルの年月接尾辞
  oCal.cfg.setProperty("MY_LABEL_YEAR_SUFFIX", "\u5E74");
  oCal.cfg.setProperty("MY_LABEL_MONTH_SUFFIX", "");

}

/**
 * 
 */
function preparePopupFileUploader(sListContainerId, sPrepareUrl, oOpts) {
  var sButton = sListContainerId + "-popup-button";
  var oButton = $(sButton);

  if (!oButton) {
    oButton = new Element("button", {
      "class" : "button-popup-file-uploader",
      type : "button",
      id : sButton
    }).update("show");
    $(sListContainerId).insert({
      after : oButton
    });
  }

  var oOptions = {};
  Object.extend(oOptions, oOpts);
  var oDialog;
  oButton.observe("click", function(o) {
    if (!oDialog) {
      var sDialogId = sListContainerId + "-container";

      function handleClickAdd() {
        $("file-upload-form").submit();
        $("file-upload-frame").contentWindow.location = sPrepareUrl;
      }
      ;

      function handleClickApply() {
        /* apply to parent edit. */
        // $(sListContainerId).update("update");
        oDialog.hide();
      }
      ;

      var oConf = {
        hideaftersubmit : false,
        modal : true,
        fixedCenter : true,
        draggable : true,
        close : true
      };
      Object.extend(oConf, {
        zIndex : 6500, /* width : w, height : h, */
        visible : false
      });
      Object.extend(oConf, {
        effect : {
          effect : YAHOO.widget.ContainerEffect.FADE,
          duration : 0.20
        }
      });
      Object.extend(oConf, {
        buttons : [ {
          text : "登録",
          handler : handleClickAdd
        }, {
          text : "閉じる",
          handler : handleClickApply,
          isDefault : true
        } ]
      });

      oDialog = new YAHOO.widget.Dialog(sDialogId, oConf);

      oDialog.setHeader("ファイル選択");

      var oDiv = new Element("div");

      var sUploadAction = "/clicksearch/app/files/upload/" + oOpts.parentType + "/" + (oOpts.parentId ? oOpts.parentId : "new"); /* FIXME */

      var oForm = new Element("form", {
        id : "file-upload-form",
        action : sUploadAction,
        method : "post",
        enctype : "multipart/form-data",
        target : "upload-result-frame"
      });
      var oDivFiles = new Element("div");
      var i;
      for (i = 0; i < 1; i++) {
        var oDivFile = new Element("div");
        var sFileId = "upload-files" + i;
        var sTitleId = "upload-files" + i;
        oDivFile.appendChild(new Element("label", {
          "for" : sFileId
        }).update("ファイル"));
        oDivFile.appendChild(new Element("input", {
          type : "file",
          name : "files[0]",
          id : sFileId
        }));
        oDivFile.appendChild(new Element("label", {
          "for" : sTitleId
        }).update("タイトル"));
        var oTitle = new Element("input", {
          type : "text",
          name : "title[0]",
          id : sTitleId
        }).observe("keypress", _voidEnterSubmit);
        oDivFile.appendChild(oTitle);
        oDivFiles.appendChild(oDivFile);
      }
      oForm.appendChild(oDivFiles);

      // var ptype = new Element("input", { type : "text", name : "parentType",
      // value : this.parentType });
      // var pid = new Element("input", { type : "text", name : "parentId",
      // value : this.parentId });
      // oForm.appendChild(ptype);
      // oForm.appendChild(pid);

      oDiv.appendChild(oForm);
      var oIFrame = new Element("iframe", {
        name : "upload-result-frame",
        src : "",
        style : "display: none;",
        id : "upload-result-frame"
      });
      // FIXME IE で動かない(親タイプと親IDが引き継げない)
      oIFrame.observe("load", function(e) {
        $("file-upload-form").reset();
        if ($("upload-result-frame").contentWindow.$$) {
          var t = $("upload-result-frame").contentWindow.$$("div.body table.form").last();
          $("attachmentFiles-container").update(t);
          // } else {
          // $("attachmentFiles-container").update(e.target.toString());
        }
      });
      oDiv.appendChild(oIFrame);

      oDialog.setBody(oDiv);

      oDialog.render(document.body);

      oDialog.showEvent.subscribe(function() {
        /* IE only. */
        if (Prototype.IE) {
          oDialog.fireEvent("changeContent", {
            handles : [ 'br' ],
            autoRatio : false,
            minWidth : 360,
            minHeight : 240,
            status : false
          });
        }
      });

      /* support resizing dialog. */
      var oResize = new YAHOO.util.Resize(sDialogId, {
        handles : [ "br" ],
        autoRatio : false,
        minWidth : 300,
        minHeight : 100,
        status : false
      });

      oResize.on("startResize", function(oArgs) {
        if (this.cfg.getProperty("constraintoviewport")) {
          var D = YAHOO.util.Dom; // short-hand
          var clientRegion = D.getClientRegion();
          var elRegion = D.getRegion(this.element);

          resize.set("maxWidth", clientRegion.right - elRegion.left - YAHOO.widget.Overlay.VIEWPORT_OFFSET);
          resize.set("maxHeight", clientRegion.bottom - elRegion.top - YAHOO.widget.Overlay.VIEWPORT_OFFSET);
        } else {
          resize.set("maxWidth", null);
          resize.set("maxHeight", null);
        }
      }, oDialog, true);

      oResize.on("resize", function(oArgs) {
        var nHeight = oArgs.height;
        this.cfg.setProperty("height", nHeight + "px");
        this.center();
      }, oDialog, true);

    }
    oDialog.show();
  });
}

/**
 * ポップアップカレンダー
 * 
 * @param sDateFieldId
 */
function prepareYUIPopupCalendar(sDateFieldId, opts) {

  var sButton = sDateFieldId + "-popup-button";

  /* 対象フィールドが月日のみ入力されている場合 */
  $(sDateFieldId).observe('blur', function(evt) {
    var el = evt.element();
    var val = el.getValue();
    var dstr = val ? val.replace(/(^\s+)|(\s+$)/, "") : "";
    var res = /^(\d{1,2})\/(\d{1,2})$/.exec(dstr);
    if (res) {
      var m = parseInt(res[1], 10) - 1;
      var d = parseInt(res[2], 10);
      var oNow = new Date();
      var oToday = new Date(oNow.getFullYear(), oNow.getMonth(), oNow.getDate());
      var curr_y = oNow.getFullYear();

      var sFlg = opts ? opts.roundYear : "current";

      switch (sFlg) {
      case "round":
        /* 最も近い年月日 round year */
        var tmp = new Date(curr_y, m, d);
        var days = [ new Date(curr_y + 1, m, d), new Date(curr_y - 1, m, d) ];
        var i;
        for (i = 0; i < days.length; i++) {
          if (Math.abs(oToday.getTime() - days[i].getTime()) <= (oToday.getTime() - tmp.getTime())) {
            tmp = days[i];
          }
        }
        m++;
        el.setValue([ tmp.getFullYear(), (m < 10 ? "0" + m : m), (d < 10 ? "0" + d : d) ].join("/"));
        break;
      case "ceil":
        /* 最も近い将来の年月日 ceil */
        var tmp = new Date(curr_y, m, d);
        if (tmp.getTime() < oToday.getTime()) {
          tmp = new Date(curr_y + 1, m, d);
        }
        m++;
        el.setValue([ tmp.getFullYear(), (m < 10 ? "0" + m : m), (d < 10 ? "0" + d : d) ].join("/"));
        break;
      case "floor":
        /* 最も近い過去の年月日 floor */
        var tmp = new Date(curr_y, m, d);
        if (tmp.getTime() > oToday.getTime()) {
          tmp = new Date(curr_y - 1, m, d);
        }
        m++;
        el.setValue([ tmp.getFullYear(), (m < 10 ? "0" + m : m), (d < 10 ? "0" + d : d) ].join("/"));
        break;
      case "current":
      default:
        /* 今年 (default) */
        var tmp = new Date(curr_y, m, d);
        m++;
        el.setValue([ curr_y, (m < 10 ? "0" + m : m), (d < 10 ? "0" + d : d) ].join("/"));
        break;
      }
    } else if (/^\d{1,4}\/\d{1,2}\/\d{1,2}$/.match(dstr)) {

    }
  });

  /* ポップアップ */
  var oButton = $(sButton);
  if (!oButton) {
    oButton = new Element("button", {
      "class" : "button-popup-calendar",
      type : "button",
      id : sButton
    });
    oButton.update(new Element("span", {
      "class" : "edit-calendar"
    }).update(new Element("br")));

    /* 対象フィールドの直後に挿入 */
    $(sDateFieldId).insert({
      after : oButton
    });
  }

  /* ポップアップダイアログ */
  var oDialog;
  /* カレンダー */
  var oCalendar;

  oButton.observe("click", function() {
    if (!oDialog) {
      /* 画面 押下 */
      YAHOO.util.Event.on(document, "click", function(e) {
        var el = YAHOO.util.Event.getTarget(e);
        var dEl = oDialog.element;
        /* ポップアップ外をクリックした場合にダイアログを閉じる。 */
        if (el != dEl && !YAHOO.util.Dom.isAncestor(dEl, el) && el != oButton && !YAHOO.util.Dom.isAncestor(oButton, el)) {
          oDialog.hide();
        }
      });

      /* リセットボタン 押下 */
      function resetHandler() {
        var selDates = oCal.getSelectedDates();
        var resetDate;
        if (selDates.length > 0) {
          resetDate = selDates[0];
        } else {
          resetDate = oCal.today;
        }
        oCal.cfg.setProperty("pagedate", resetDate);
        oCal.render();
      }

      /* 閉じるボタン 押下 */
      function closeHandler() {
        oDialog.hide();
      }

      /* ポップアップダイアログ */
      oDialog = new YAHOO.widget.Dialog(sDateFieldId + "-container", {
        visible : false,
        context : [ sButton, "tl", "bl" ],
        draggable : false,
        close : true,
        effect : {
          effect : YAHOO.widget.ContainerEffect.FADE,
          duration : 0.20
        }
      });

      oDialog.setHeader("日付選択");
      var sDialogBody = "<div id='" + sDateFieldId + "-calendar'></div><div style='clear: both'></div>";
      oDialog.setBody(sDialogBody);

      oDialog.render(document.body);

      oDialog.showEvent.subscribe(function() {
        /* */
        if (Prototype.Browser.IE) {
          oDialog.fireEvent("changeContent");
        }
      });
    }

    if (!oCalendar) {
      var oNavConf = {
        strings : {
          month : "月",
          year : "年",
          submit : "OK",
          cancel : "キャンセル",
          invalidYear : "有効な年を入力してください。"
        }
      };

      var oCalConf = {
        iframe : false,
        hide_blank_weeks : true,
        navigator : oNavConf
      };

      var oRE = /(\d+)\/(\d+)\/(\d+)/;
      if ($(sDateFieldId).value && $(sDateFieldId).value.match(oRE)) {
        /* convert date format yyyy/MM/dd to MM/dd/yyyy. */
        var replaced = $(sDateFieldId).value.replace(oRE, "$2/$3/$1");
        oCalConf.selected = replaced;

      }
      oCalendar = new YAHOO.widget.Calendar(sDateFieldId + "-calendar", oCalConf);

      japanizedCalendar(oCalendar);

      oCalendar.render();

      oCalendar.selectEvent.subscribe(function() {
        if (oCalendar.getSelectedDates().length > 0) {
          var selDate = oCalendar.getSelectedDates()[0];

          var d = selDate.getDate();
          var m = selDate.getMonth() + 1;
          var y = selDate.getFullYear();
          $(sDateFieldId).value = y + "/" + (m < 10 ? "0" + m : m) + "/" + (d < 10 ? "0" + d : d);
        } else {
          $(sDateFieldId).value = "";
        }
        oDialog.hide();
      });

      oCalendar.renderEvent.subscribe(function() {
        oDialog.fireEvent("changeContent");
      });
    }

    $(sDateFieldId).observe("change", function(o) {
      var oElement = o.element();
      var oRE = /(\d+)\/(\d+)\/(\d+)/;
      if (oElement.value && oElement.value.match(oRE)) {
        // /* convert date format yyyy/MM/dd to MM/dd/yyyy. */
        // var replaced = oElement.value.replace(oRE, "$2/$3/$1");

        oCalendar.select(oElement.value);
        var sdates = oCalendar.getSelectedDates();
        if (sdates.length > 0) {
          var fdate = sdates.first();
          oCalendar.cfg.setProperty("pagedate", (fdate.getMonth() + 1) + "/" + fdate.getFullYear());
          oCalendar.render();
        }
      }
    });

    var seldate = oCalendar.getSelectedDates();
    if (seldate.length > 0) {
      oCalendar.cfg.setProperty("pagedate", seldate[0]);
      oCalendar.render();
    }

    oDialog.show();

  });
}

function prepareYUIXHRDataSourceXML(sUrl, oSchema) {
  var oDS = new YAHOO.util.XHRDataSource(sUrl);
  oDS.responseType = YAHOO.util.XHRDataSource.TYPE_XML;
  oDS.responseSchema = oSchema;
  return oDS;
}
/**
 * 
 */
function prepareYUIAutoComplete(sInputId, oDataSource, oConfig) {
  var sAC = sInputId + "-ac";
  var sContainerId = sInputId + "-ac-container";
  if (!$(sAC)) {
    var opts = oConfig.acConfig || {};
    opts.id = sAC;
    $(sInputId).wrap(new Element("div", opts));
  }
  if (!$(sContainerId)) {
    var opts = oConfig.containerConfig || {};
    opts.id = sContainerId;
    $(sInputId).insert({
      after : new Element("div", opts)
    });
  }
  var oAC = new YAHOO.widget.AutoComplete(sInputId, sContainerId, oDataSource);

  oAC.useShadow = true;
  oAC.useIFrame = true;

  /* リクエスト生成 */
  if (oConfig.fnGenerateRequest) {
    oAC.generateRequest = oConfig.fnGenerateRequest;
  }

  /* 結果項目フォーマット */
  if (oConfig.fnFormatResult) {
    oAC.formatResult = oConfig.fnFormatResult;
  }

  /* 結果項目選択イベント */
  if (oConfig.fnHandleItemSelectEvent) {
    oAC.itemSelectEvent.subscribe(oConfig.fnHandleItemSelectEvent);
  }

  return oAC;
}

/**
 * 指定されたanchorタグのhrefから削除フォームを生成する。
 */
function confirmDestroy(oAnchor) {
  /* confirmatin for destroy. */
  if (confirm('Are you sure?')) {
    /* create form. */
    var f = new Element("form", {
      method : "POST",
      action : oAnchor.href
    });
    f.style.display = "none";
    // oAnchor.parentNode.appendChild(f);
    document.body.appendChild(f);

    /* add delete method. */
    var m = new Element("input", {
      type : "hidden",
      name : "_method",
      value : "delete"
    });
    f.appendChild(m);

    /* submit. */
    f.submit();
  }
}

/**
 * 指定されたurlのプレースホルダにパラメータを置換する。 replaceUrl("/app/{controller}/{id}",
 * {controller: "users", id: 10}) =>
 */
function replaceUrl(sUrlTpl, oParams) {
  return sUrlTpl.replace(/\{(.+?)\}/g, function($0, $1) {
    return (oParams[$1]) ? oParams[$1] : $0;
  });
}

function openSimpleWindow(sUrl, sWin, opts) {
  var oOpts = {
    menubar : "no",
    toolbar : "no",
    status : "no",
    location : "no",
    resizable : "no",
    scrollbars : "no"
  };

  if (opts) {
    oOpts = $H(oOpts).merge($H(opts)).toObject();
  }

  var aOpts = [];

  for (n in oOpts) {
    aOpts.push(n + "=" + oOpts[n]);
  }

  var sOpts = aOpts.join();
  var win = window.open(sUrl, sWin, sOpts);
  if(win.focus){
    win.focus();
  }
  return win;
}

/**
 * カーソル上下移動（dojo使用）
 * 
 * @param keyEvent
 *            キーイベント
 * @param upDijit
 *            上部フィールド（未指定時、null）
 * @param downDijit
 *            下部フィールド（未指定時、null）
 * @returns {Boolean}
 */
function handleUpDown(keyEvent, upDijit, downDijit) {
  switch (keyEvent.keyCode) {
  case dojo.keys.ENTER:
    dojo.stopEvent(keyEvent);
    if (keyEvent.shiftKey) {
      if (upDijit) {
        dijit.byId(upDijit).focus();
      }
    } else {
      if (downDijit) {
        dijit.byId(downDijit).focus();
      }
    }
    break;
  case dojo.keys.UP_ARROW:
    if (upDijit) {
      dojo.stopEvent(keyEvent);
      dijit.byId(upDijit).focus();
    }
    break;
  case dojo.keys.DOWN_ARROW:
    if (downDijit) {
      dojo.stopEvent(keyEvent);
      dijit.byId(downDijit).focus();
    }
    break;
  default:
    break;
  }
  return true;
}
