if(!dojo._hasResource["aipo.schedule.dnd.OneDayScheduleMove"]){
dojo._hasResource["aipo.schedule.dnd.OneDayScheduleMove"] = true;
/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * http://www.aipo.com/
 *
 * Copyright(C) 2012 avanza Co.,Ltd. All rights reserved.
 * http://www.avnz.co.jp/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
// 1日スケジュール通常予定クリック・ドラッグ＆ドロップ
dojo.provide("aipo.schedule.dnd.OneDayScheduleMove");

dojo.require("aimluck.dnd.Draggable");
dojo.require("aipo.common");
dojo.require("aipo.widget.ToolTip");
dojo.require("aipo.schedule");
dojo.require("aipo.schedule.oneday");
dojo.require("aipo.schedule.dnd.ScheduleToolTipFoundation");

/**
 * 1日スケジュール用通常予定クリック・ドラッグ＆ドロップ実体
 */
dojo.declare("aipo.schedule.dnd.OneDayScheduleDragMoveObject", [aimluck.dnd.DragMoveObject], {
    /** マウスドラッグ（初期処理） */
    onFirstMove: function(e){
        // コピー元予定の描画のため、ダミー予定を作成
        this.copySourceNode = dojo.clone(this.node);
        this.copySourceNode.id = 'schedule-dummy_' + this.portletId;
        this.copySourceNode.style.zIndex = 998;
        dojo.style(this.copySourceNode, "opacity", 0.0);
        var garage = dojo.byId('scheduleGarage_' + this.portletId);
        garage.appendChild(this.copySourceNode);

        var tmpCopySourceNode = this.copySourceNode;
        // ブラウザ別設定
        if (dojo.isIE) {
            // IEの場合
            // documentのキー押下イベントに透過度設定をおこなう
            document.onkeydown = function(e) {
                dojo.style(tmpCopySourceNode, "opacity", 0.5);
            };
            document.onkeyup = function(e) {
                dojo.style(tmpCopySourceNode, "opacity", 0.0);
            };
        } else {
            // IE以外はグローバルなキー押下イベントハンドラを作成する
            dojo.connect(null, "onkeydown", this, "onKeyPress");
            dojo.connect(null, "onkeyup", this, "onKeyPress");
        }

        // 親メソッドを実行
        aimluck.dnd.DragMoveObject.prototype.onFirstMove.apply(this, arguments);

        // 透過度設定
        dojo.style(this.node, "opacity", 0.8);
        // ドラッグ対象を最前面へ移動
        this.node.style.zIndex = 999;
        // マウス押下時のマウスカーソルY座標
        this.startY = this._pageY;
        // ドラッグ対象のY座標（絶対）
        this.startNodeAbsoluteY = dojo._abs(dojo.byId(this.node), true).y;

        //Google Chrome及びSafari、Firefox3.6以降ではdojo._absの挙動が異なるので、AbsoluteXを修正する
        var userAgent = window.navigator.userAgent.toLowerCase();
        if (userAgent.indexOf("chrome") > -1 || (dojo.isFF && (dojo.isFF >= 3.6))) {
            // ページスクロール分を修正
            this.startNodeAbsoluteY += window.scrollY;
        } else if(userAgent.indexOf("safari") > -1) {
            // DIVタグスクロール分を修正
            this.startNodeAbsoluteY -= dojo.byId('weeklyScrollPane_'+this.portletId).scrollTop;
        }

        // ドラッグ対象のX座標（相対）
        this.startX =  dojo.getComputedStyle(this.node).left;
        // ドラッグ対象のY座標（相対）
        this.startTop = parseInt(dojo.getComputedStyle(this.node).top);
        // ドラッグ対象の縦幅
        this.startHeight = parseInt(dojo.getComputedStyle(this.node).height);
        // ドラッグ対象を移動か縦幅変更か判定
        if(this.startHeight - 6 < this.startY-this.startNodeAbsoluteY) {
            // 縦幅変更の場合
            this.isResize = true;
        }else{
            // 移動の場合
            this.isResize = false;
        }

        // 列グリッド配列を生成
        aipo.schedule.oneday.setGridArray(this.portletId, this.dragSource.member.options.length);
        // スクロール現在位置を取得
        this.lastScroll = dojo.byId('weeklyScrollPane_'+this.portletId).scrollTop;
    },
    // キー押下
    onKeyPress: function(e){
        // キー別にコピー元予定の透過度設定をおこなう
        if(e.ctrlKey) {
            // コントロールキー押下の場合
            dojo.style(this.copySourceNode, "opacity", 0.5);
        } else {
            // 他のキー押下の場合
            dojo.style(this.copySourceNode, "opacity", 0.0);
        }
    },
    /** マウスドラッグ */
    onMouseMove: function(e){

        // ドラッグ不可の予定
        if(this.dragSource.isDraggable == false) return;

        // 親メソッドを実行
        aimluck.dnd.DragMoveObject.prototype.onMouseMove.apply(this, arguments);
        // ドラッグ中と確定
        this.dragSource.isDrag = true;

        // ドラッグ時の縦幅最小値
        var distance = ptConfig[this.portletId].distance;

        // 縦幅が最小幅未満の場合、実際の幅で描画する
        if(this.dragSource.tmpHeight != -1) {
            dojo.style(this.node, "height", this.dragSource.tmpHeight + "px");
        }

        // 現スクロール位置とドラッグ開始時のスクロール位置の差より、ドラッグ対象の移動先Y座標（相対）を算出
        var distance_scr = dojo.byId('weeklyScrollPane_'+this.portletId).scrollTop - this.lastScroll;
        this.leftTop.t = Math.floor((this.leftTop.t + distance_scr )/distance)*distance;

        // ドラッグ対象の座標更新
        if (this.isResize) {
            // 縦幅変更の場合
            if(- this.startTop + this.leftTop.t + this.startHeight < 0) {
                // 縦幅を修正前以下に短くした場合、縦幅0pxで上方向へ移動する
                dojo.style(this.node, "height", "0px");
                //this.leftTop.t += this.startHeight;
            } else {
                // 変更後の縦幅で描画する
                // 縦幅が領域を超える場合は、それ以上長くしない
                var rh;
                if (this.leftTop.t + this.startHeight > 864 ) {
                    rh = 864 - this.startTop - distance;
                } else {
                    rh =  - this.startTop + this.leftTop.t + this.startHeight;
                }
                this.leftTop.t = this.startTop;
                this.leftTop.h = parseInt(rh) -1;
            }
        } else {
            // 移動の場合
            if(!this.disableY) {
                // 予定Y座標が0未満の場合は0にする
                if ( this.leftTop.t < 0 ) {
                    this.leftTop.t = 0;
                }
                if ( this.leftTop.t + this.startHeight > 864){
                    // 予定Y座標+予定縦幅が領域を超える場合
                    if(this.dragSource.strloc == "S"){
                        // 日またぎの場合、予定の縦幅を調整する
                        var wHeight = 864 - this.leftTop.t - 1;
                        if( wHeight<1 ) {
                            return;
                        }
                        dojo.style(this.node, "height", wHeight + "px");
                    }else{
                        // 他の予定の場合、予定のY座標を調整する
                        this.leftTop.t = 864 - this.startHeight - 6;
                    }
                }
            }
        }
        // ドラッグ対象のX座標を、ドラッグ開始時から固定化
        this.leftTop.l = this.startX;

        // ドラッグ対象を移動先へ描画
        dojo.marginBox(this.node, this.leftTop);

        // ドラッグ対象の開始時刻変更
        var tmpTop = parseInt(dojo.getComputedStyle(this.node).top);
        var tmpHeight = parseInt(dojo.getComputedStyle(this.node).height);
        var quotient = tmpTop/distance;
        var hour = Math.floor(quotient/12);
        var minute = Math.floor(quotient%12);
        hour = (hour > 9)? hour : "0" + hour;
        minute = (minute > 1) ? minute*(60/12): "0" + minute*(60/12);
        var id = this.dragSource.count;
        this.dragSource.schedule.startDateHour = hour;
        this.dragSource.schedule.startDateMinute = minute;
        this.dragSource.schedule.startDate = hour + ':'+ minute;

        // ドラッグ対象の終了時刻変更
        quotient += tmpHeight/distance;
        hour = Math.floor(quotient/12);
        minute = Math.floor(quotient%12);
        hour = (hour > 9)? hour : "0" + hour;
        minute = (minute > 1) ? minute*(60/12): "0" + minute*(60/12);
        this.dragSource.schedule.endDateHour = hour;
        this.dragSource.schedule.endDateMinute = minute;
        this.dragSource.schedule.endDate = hour + ':'+ minute;

        return;
    },
    /** マウスドロップ */
    onMouseUp: function (e) {

        // ツールチップを有効にする
        ptConfig[this.portletId].isTooltipEnable = true;

        // IEの場合、全体のキー押下イベントハンドラを初期化する
        if (dojo.isIE) {
            document.onkeydown = "";
            document.onkeyup = "";
        }

        // 日またぎの操作
        // ドロップ終了日付列位置の取得
        var endColIndex = null;
        if(this.dragSource.strloc == "S" || this.dragSource.strloc == "M" || this.dragSource.strloc == "E"){
            endColIndex = aipo.schedule.oneday.getCurrentMouseX(e);
        }

        // ドラッグ中で無い場合、クリック時の操作を実施（ドラッグ可能予定はonclickイベントが拾えないため）
        if(this.dragSource.isDrag != true){
            dojo.style(this.node, "opacity", 1.0 );
            aimluck.dnd.DragMoveObject.prototype.onMouseUp.apply(this, arguments);
            this.dragSource.onScheduleClick(e);
            return;
        }

        // 縦幅が30分未満か否かを格納
        var mouseUpHeight = parseInt(dojo.getComputedStyle(this.node).height);
        if(mouseUpHeight < ptConfig[this.portletId].rowHeight) {
            // 30分未満の場合、描画する縦幅を最小縦幅に変更し、実際の縦幅を保持する
            dojo.style(this.node, "height", ptConfig[this.portletId].rowHeight+ "px");
            this.dragSource.tmpHeight = mouseUpHeight;
        } else {
            // 30分超の場合、-1を保持する
            this.dragSource.tmpHeight = -1;
        }

        // 更新可否判定
        // 確認ダイアログを表示する
        var update_flg = confirm("予定を変更しますが、よろしいですか？");
        if(update_flg == false){
            // 確認ダイアログでキャンセルした場合は、更新せずに終了する
            aipo.schedule.oneday.loadSchedule(this.portletId, "");
            aipo.portletReload('schedule', this.portletId);
            aimluck.dnd.DragMoveObject.prototype.onMouseUp.apply(this, arguments);
            this.dragSource.destroy();
            return;
        }

        // 更新処理
        // リクエストパラメータの生成
        var params = "";
        // 処理モード
        if(e.ctrlKey) {
            params += "&mode=insert";
        } else {
            params += "&mode=update";
        }

        // エンティティID
        params += "&entityid="+ this.dragSource.schedule.scheduleId;

        // 繰り返し予定の場合、フラグと処理対象日
        if(this.dragSource.schedule.repeat) {
            params += "&edit_repeat_flag=1";
            params += "&view_date=" + ptConfig[this.portletId].jsonData.formDateTime.substring(0, 10);
        }

        if(this.dragSource.strloc == "S" || this.dragSource.strloc == "M" || this.dragSource.strloc == "E") {
            // 日またぎ予定の場合
            var days = 0;
            if(endColIndex){
                // 開始位置と終了位置の差分（日数）を取得
                days = endColIndex.index - this.dragSource.tmpIndex;
            }
            if(days == 0 && this.dragSource.strloc == "S"){
                // 日数なし かつ 開始時刻変更の場合
                params += "&straddle_mode=changeStartTime";
                params += "&straddle_start_time=" + ptConfig[this.portletId].jsonData.formDateTime.substring(0, 11) + this.dragSource.schedule.startDateHour + '-' + this.dragSource.schedule.startDateMinute;
            }else if(days == 0 && this.dragSource.strloc == "E"){
                // 日数なし かつ 終了時刻変更の場合
                params += "&straddle_mode=changeEndTime";
                params += "&straddle_end_time=" + ptConfig[this.portletId].jsonData.formDateTime.substring(0, 11) + this.dragSource.schedule.endDateHour + '-' + this.dragSource.schedule.endDateMinute;
            }else{
                // 日付変更の場合
                params += "&straddle_mode=changeDay";
                params += "&days=" + days;
            }
        }else{
            // その他の予定の場合、開始日時と終了日時
            params += "&start_date=" + ptConfig[this.portletId].jsonData.formDateTime.substring(0, 11) + this.dragSource.schedule.startDateHour + '-' + this.dragSource.schedule.startDateMinute;
            params += "&end_date=" + ptConfig[this.portletId].jsonData.formDateTime.substring(0, 11) + this.dragSource.schedule.endDateHour + '-' + this.dragSource.schedule.endDateMinute;
        }

        // 終了する
        aipo.schedule.oneday.loadSchedule(this.portletId, params);
        aipo.portletReload('schedule', this.portletId);
        aimluck.dnd.DragMoveObject.prototype.onMouseUp.apply(this, arguments);
        this.dragSource.destroy();
    }
});

/**
 * 1日スケジュール用通常予定ドラッグ＆ドロップコントローラー
 */
dojo.declare("aipo.schedule.dnd.OneDayScheduleDraggable", [aimluck.dnd.Draggable], {
    // Mpverクラス
    DragMoveObject: aipo.schedule.dnd.OneDayScheduleDragMoveObject,
    // ドラッグ可否
    isDraggable: false,
    // ドラッグ中
    isDrag: false,
    // 照会可否
    canReference: false,
    // 日またぎ位置情報
    strloc: "",
    // ドラッグ対象要素のスケジュール
    schedule: null,
    // ドラッグ対象要素の列番号
    tmpIndex: 0,
    // ドラッグ対象要素の通し番号
    count: 0,
    // ドラッグ対象要素の縦幅（30分未満の場合のみ。それ以外は-1）
    tmpHeight:-1,
    constructor: function(node, params){
        this.member = dojo.byId('member_to-' + this.portletId);
    },
    /** マウス押下 */
    onMouseDown: function(e){
        // add start 要件No.16　スケジュール画面（月単位／週単位／日単位）右クリックメニュー
        if( e.button == 2 || e.button == 4 ) {
            return;
        }
        // add end

        // ツールチップ土台を削除する
        if(!!aipo.schedule.oneday.dummyDivObj && !!aipo.schedule.oneday.dummyDivObj.tooltipObject){
            aipo.schedule.oneday.dummyDivObj.tooltipObject.close();
        }
        // ツールチップを無効にする
        ptConfig[this.portletId].isTooltipEnable = false;
        // 親メソッドを実行する(moverを生成)
        aimluck.dnd.Draggable.prototype.onMouseDown.apply(this, arguments);
    },
    /** クリック */
    onScheduleClick: function(e) {
        // add start 要件No.16　スケジュール画面（月単位／週単位／日単位）右クリックメニュー
        if( e.button == 2 || e.button == 4 ) {
            return;
        }
        // add end

        // 照会可否フラグで操作可否をチェック
        if(this.schedule.isDrag || !this.canReference) {
            return;
        }
        // スケジュール詳細を開く
        aipo.common.showWindow(
            ptConfig[this.portletId].detailUrl
            + "&entityId=" + this.schedule.scheduleId
            + "&view_date=" + ptConfig[this.portletId].jsonData.formDateTime
            + "&userid=" + this.schedule.ownerId,
            this.portletId,
            aipo.schedule.onLoadScheduleDetail );
        // IEで追加ダイアログを閉じるとスクロールバーのｙ座標が強制的に0になってしまう現象の対策用
        aipo.schedule.tmpScroll = parseInt(dojo.byId('weeklyScrollPane_'+this.portletId)["scrollTop"], 10);
    },
    // add start 要件No.16　スケジュール画面（月単位／週単位／日単位）右クリックメニュー
    onRightClick: function(e) {

      var uid = this.schedule.ownerId;
      var secid = dojo.byId('secid-' + this.portletId).value;
      var baseUrl = ptConfig[this.portletId].thisUrl + "?entityId=" + this.schedule.scheduleId + "&view_date=" + ptConfig[this.portletId].jsonData.formDateTime;
      var detailUrl = ptConfig[this.portletId].detailUrl + "&entityId=" + this.schedule.scheduleId + "&view_date=" + ptConfig[this.portletId].jsonData.formDateTime + "&userid=" + uid;
      var hasMember = "false";
      var item = this.schedule;
      if(item.memberList){
          var ucount = 0;
          var fcount = 0;
          for (j = 0 ; j < item.memberList.length ; j ++){
              if(item.memberList[j].charAt(0) == 'f'){
                  fcount++;
              }else{
                  ucount++;
              }
          }
          if( ucount > 1 ) {
            hasMember = "true";
          }
      }
      // ツールチップ土台を削除する
      if(!!aipo.schedule.oneday.dummyDivObj && !!aipo.schedule.oneday.dummyDivObj.tooltipObject){
          aipo.schedule.oneday.dummyDivObj.tooltipObject.close();
      }
      //コンテキストメニュー表示
      aipo.schedule.common.showMenu(
          e,
          this.portletId,
          detailUrl,
          baseUrl,
          this.schedule.status,
          this.schedule.priority ? "true" : "false",
          this.schedule.repeat ? "true" : "false",
          this.schedule.member ? "true" : "false",
          this.schedule.organizer ? "true" : "false",
          hasMember,
          this.schedule.loginuser ? "true" : "false",
          uid,
          secid,
          this.node,
          aipo.schedule.oneday.loadSchedule);

      e.preventDefault();
      e.stopPropagation();
    },
    onRightClickForNonPulic: function(e) {
      //非公開のスケジュールを右クリックした場合に標準のコンテキストメニューの表示を抑止
      e.preventDefault();
      e.stopPropagation();
    },
    // add end
    /** マウスオーバー */
    onScheduleOver: function(e) {
        // 照会可否フラグで操作可否をチェック
        if(!this.canReference){
            return;
        }
        // ツールチップ無効中は処理を終了する
        if(ptConfig[this.portletId].isTooltipEnable == false){
            return;
        }
        // ツールチップの土台を生成する
        var ttdiv = dojo.byId("dummy_div_" + this.portletId);
        var left =  dojo.getComputedStyle(this.node).left ;
        var top =  dojo.getComputedStyle(this.node).top;
        var width =  dojo.getComputedStyle(this.node).width;
        var height =  dojo.getComputedStyle(this.node).height;
        dojo.marginBox (ttdiv,dojo._getMarginBox(this.node,{ l: left, t: top, w: width, h: height }));
        ttdiv.style.zIndex = this.node.style.zIndex ;
        ttdiv.style.height = (parseInt(height) - 6) + "px";
        if(!aipo.schedule.oneday.dummyDivObj){
            aipo.schedule.oneday.dummyDivObj = new aipo.schedule.dnd.ScheduleToolTipFoundation(ttdiv ,
                    {pid: this.node.id,
                    parentnode: this.node,
                    draggable: this});
        }else{
            aipo.schedule.oneday.dummyDivObj.parentnode = this.node;
            aipo.schedule.oneday.dummyDivObj.draggable = this;
        }

        // 前回のツールチップ土台を削除する
        if(aipo.schedule.oneday.dummyDivObj.tooltipObject){
            aipo.schedule.oneday.dummyDivObj.tooltipObject.destroyRecursive();
            aipo.schedule.oneday.dummyDivObj.tooltipObject = null;
        }

        // ツールチップ表示
        // IPADではツールチップ非表示
        if (scheduleTooltipEnable) {
            this.setupTooltip();
        }
    },
    /** ツールチップ表示 */
    setupTooltip: function() {
        var pid = this.portletId;
        var sid = this.schedule.scheduleId;
        aipo.schedule.oneday.dummyDivObj.tooltipObject = new aipo.widget.ToolTip({
            label: "<div class='indicator'>読み込み中...</div>",
            connectId: ["dummy_div_" + this.portletId]},
            this.portletId,
            function(containerNode, node){
                var request_url = ptConfig[pid].jsonUrl.split("?")[0]
                    + "?template=ScheduleDetailJSONScreen"
                    + "&view_date=" + ptConfig[pid].jsonData.startDate
                    + "&scheduleid="+ sid;
                aipo.schedule.oneday.showTooltip(request_url, pid, containerNode);
            }
        );
    }
});

}