﻿var scheduleMgr;

//////// ロード ////////////////////////////////////////
function load(w, o) {
    scheduleMgr = new ScheduleMgr(w, o);
}

//**********************************************************************
//scheduleMgr
//**********************************************************************
var ScheduleMgr = Class.create();
ScheduleMgr.prototype = {
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //コンストラクタ
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    initialize: function(w, o)
    {
        //////// 定数 //////////////////////////////
        this.DAY_TIME = 24 * 60 * 60 * 1000;
        this.WEEK_TIME = 7 * this.DAY_TIME;
        this.weekTbl = new Array('日', '月', '火', '水', '木', '金', '土');

        //////// 初期化 //////////////////////////////
        this.basePanel = $('schedule');
        this.walkerId = w;
        this.isOwner = o;
        this.dragging = false;
        
        today = new Date();
        this.baseDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
        
        //////// エレメント生成 //////////////////////////////
        this.createElement();

        //////// 表示 //////////////////////////////
        this.request();
    }
    //////// エレメント生成 ////////////////////////////////////////
    ,createElement: function()
    {
        var el = document.createElement('div');
        this.basePanel.appendChild(el);
        this.ctrlPanel = el;

        //////// メニュー ////////////////////////
        el = document.createElement('ul');
        this.ctrlPanel.appendChild(el);
        this.mainMenu = el;
        
        var li = document.createElement('li');
        this.mainMenu.appendChild(li);
        el = document.createElement('a');
        el.href = 'javascript:;';
        el.innerHTML = '前の週';
        el.onclick = this.prevWeek.bindAsEventListener(this);
        li.appendChild(el);
        
        li = document.createElement('li');
        this.mainMenu.appendChild(li);
        el = document.createElement('a');
        el.href = 'javascript:;';
        el.innerHTML = '今週';
        el.onclick = this.thisWeek.bindAsEventListener(this);
        li.appendChild(el);
        
        li = document.createElement('li');
        this.mainMenu.appendChild(li);
        el = document.createElement('a');
        el.href = 'javascript:;';
        el.innerHTML = '次の週';
        el.onclick = this.nextWeek.bindAsEventListener(this);
        li.appendChild(el);
        
//        if (this.isOwner) {
//            li = document.createElement('li');
//            this.mainMenu.appendChild(li);
//            el = document.createElement('a');
//            el.href = 'javascript:;';
//            el.innerHTML = '予定を追加する';
//            el.onclick = this.appendSchedule.bindAsEventListener(this);
//            li.appendChild(el);
//        }

        //////// 編集パネル ////////////////////////
        if (this.isOwner) {
//            el = document.createElement('div');
//            el.setAttribute('id', 'editPanelBackground');
//            document.body.appendChild(el);
//            this.editPanelBackground = el;
        
            el = document.createElement('div');
            el.setAttribute('id', 'editPanel');
            this.basePanel.appendChild(el);
            this.editPanel = el;
            
            el = document.createElement('div');
            el.className = 'editPanelHeader';
            this.editPanel.appendChild(el);
            this.editPanelHeader = el;
            Event.observe(this.editPanelHeader, "mousedown", this.mousedown.bindAsEventListener(this), false);
            Event.observe(document, "mousemove", this.mousemove.bindAsEventListener(this), false);
            Event.observe(document, "mouseup", this.mouseup.bindAsEventListener(this), false);

            el = document.createElement('div');
            el.className = 'editPanelBody';
            this.editPanel.appendChild(el);
            this.editPanelBody = el;
            
            div = document.createElement('div');
            this.editPanelBody.appendChild(div);
            
            el = document.createElement('input');
            el.setAttribute('id', 'txtDate');
            el.setAttribute('type', 'text');
            div.appendChild(el);
            this.txtDate = el;
            
            a = document.createElement('a');
            a.href = "javascript:showCalendar($('txtDate'));";
            div.appendChild(a);
            
            img = document.createElement('img');
            img.src = '../images/icon_cal.png';
            img.alt = 'カレンダーで選ぶ';
            img.border = '0';
            a.appendChild(img);
            
            el = document.createElement('textarea');
            el.setAttribute('id', 'txtBody');
            this.editPanelBody.appendChild(el);
            this.txtBody = el;

            el = document.createElement('div');
            el.className = 'editPanelFooter';
            this.editPanel.appendChild(el);
            this.editPanelFooter = el;
            
            el = document.createElement('input');
            el.type = 'button';
            el.value = '決定';
            el.onclick = this.editSubmit.bindAsEventListener(this);
            this.editPanelFooter.appendChild(el);

            el = document.createElement('input');
            el.type = 'button';
            el.value = '戻る';
            el.onclick = this.editCancel.bindAsEventListener(this);
            this.editPanelFooter.appendChild(el);

            el = document.createElement('input');
            el.type = 'button';
            el.value = '削除';
            el.onclick = this.editDelete.bindAsEventListener(this);
            this.editPanelFooter.appendChild(el);
            this.btnDel = el;

            this.showEditPanel(false);
        }

        //====== schedule表示領域 ========        
        el = document.createElement('div');
        this.basePanel.appendChild(el);
        this.scheduleBasePanel = el;

        //====== 下部 ========
        if (this.isOwner) {
            el = document.createElement('div');
            el.setAttribute('id', 'note');
            el.innerHTML = 
                '新しい予定を入れるには、日付をクリックしてください。<br />' +
                '既に入っている予定を編集するには、予定をクリックしてください。';
            el.style.marginRight = '15px';
            this.basePanel.appendChild(el);
        }
        
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //IO
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //////// XMLをリクエスト //////////////////////////////////////////////////
    ,request: function()
    {
        var requestUrl = '/blog/schedule/sch/index/' + this.walkerId + '/' +
            this.baseDate.getFullYear() + '/' +
            (this.baseDate.getMonth() + 1) + '/' +
            this.baseDate.getDate();

        //====== XMLをRequest ========
        var myAjax = new Ajax.Request(
            requestUrl + '/' + (new Date()).getTime(),
            {
	            method: 'get'
	            ,onSuccess: this.analizeXml.bindAsEventListener(this)
	            ,onFailure: function(){
	                alert('XMLをロードできませんでした。\n');
                    this.infoPanel.style.display = "none";
                    this.points = new Array();
                    this.markers = new Array();
                }.bindAsEventListener(this)
            });
    }
    //////// 取得したXMLを解析 //////////////////////////////////////////////////
    ,analizeXml: function(originalRequest)
    {
        var xmlDoc = originalRequest.responseXML.documentElement;
        this.schedules = new Array();

        for (var node = xmlDoc.firstChild; node; node = node.nextSibling) {
            var schedule = new Schedule();
            if (schedule.load(node)) {
                this.schedules.push(schedule);
            }
        }
    
        this.showSchedule();
    }
    //////// XMLをポスト //////////////////////////////////////////////////
    ,post:function(schedule, mode)
    {
        var xmlString = '<?xml version="1.0" encoding="utf-8" ?>\n<schedules>\n' + schedule.toXmlString() + '</schedules>\n';
        var url = '../schedule/sch/' + mode + '/' + this.walkerId;
        
        new Ajax.Request(url, {
            method: "post"
            ,contentType: 'text/xml'
            ,postBody: xmlString
            ,onSuccess:function(request){
                //終了
                if (request.responseText.length > 0) {
                    alert(request.responseText);
                }
                else {
                    this.request();
                }
                this.cancel(null);
                }.bindAsEventListener(this)
            ,onFailure:function(request){
                alert('失敗しました\n');
                this.cancel(null);
                }
            });
        
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //表示系
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //////// データを表示 //////////////////////////////////////////////////
    ,showSchedule: function()
    {
//        if (this.schedulePanel) {
//            this.scheduleBasePanel.removeChild(this.schedulePanel);
//        }
        this.scheduleBasePanel.innerHTML = '';
        
        el = document.createElement('dl');
        el.setAttribute('id', 'sch');
        this.scheduleBasePanel.appendChild(el);
        this.schedulePanel = el;
        
        //====== 一覧生成 ========
        for (var i = 0; i < 7; i++) {
            di = new Date();
            di.setTime(this.baseDate.getTime() + i * this.DAY_TIME);
            
            //------ 日付 --------
            dt = document.createElement('dt');
            this.schedulePanel.appendChild(dt);
            
            if (this.isOwner) {
                el = document.createElement('a');
                el.href = 'javascript:;';
                el.onclick = this.appendSchedule.bindAsEventListener(this, di);
            }
            else {
                el = document.createElement('span');
            }
            el.innerHTML = this.getDateString(di);
            dt.appendChild(el);

            //------ 内容 --------
            dd = document.createElement('dd');
            this.schedulePanel.appendChild(dd);

            for (var j = 0; j < this.schedules.length; j++) {
                var schedule = this.schedules[j];
                var s = schedule.scheduleDate;
                if (di.getTime() == schedule.scheduleDate.getTime()) {
                    if (this.isOwner) {
                        el = document.createElement('a');
                        el.href = 'javascript:;';
                        el.onclick = this.editSchedule.bindAsEventListener(this, schedule);
                    }
                    else {
                        el = document.createElement('span');
                    }
                    el.innerHTML += schedule.scheduleBody + '<br />';
                    dd.appendChild(el);
                }
            }
        }
    }
    //////// 前の週 //////////////////////////////////////////////////
    ,prevWeek: function()
    {
        this.baseDate.setTime(this.baseDate.getTime() - this.WEEK_TIME);
        this.request();
    }
    //////// 今週 //////////////////////////////////////////////////
    ,thisWeek: function()
    {
        today = new Date();
        this.baseDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
        this.request();
    }
    //////// 次の週 //////////////////////////////////////////////////
    ,nextWeek: function()
    {
        this.baseDate.setTime(this.baseDate.getTime() + this.WEEK_TIME);
        this.request();
    }
    //////// 日付文字列 //////////////////////////////////////////////////
    ,getDateString: function(d)
    {
        year = d.getFullYear();
        
        month = d.getMonth() + 1;
//        if (month < 10) {month = '0' + month;}
        
        date = d.getDate();
//        if (date < 10) {date = '0' + date;}
        
        week = d.getDay();
        
        return year + '/' + month + '/' + date + '(' + this.weekTbl[week] + ')';
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //操作
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //////// 編集パネル表示設定 //////////////////////////////////////////////////
    ,showEditPanel:function(show, headerText, schedule)
    {
        if (show) {
            //ヘッダ
            this.editPanelHeader.innerHTML = headerText;
            
            //ボディ
            if (schedule) {
                this.txtDate.value =
                    schedule.scheduleDate.getFullYear() + '/' + 
                    (schedule.scheduleDate.getMonth() + 1) + '/' + 
                    schedule.scheduleDate.getDate();
                this.txtBody.value = schedule.scheduleBody.replace(/\<br \/\>/g, "\n").HTMLDecode();
                
                this.btnDel.style.display = (schedule.scheduleNo == 0) ? 'none' : 'inline';
            }

            //表示する
            this.editPanel.style.display = 'block';

            //座標
            var clientWidth = window.innerWidth;
            if (!clientWidth) {clientWidth = document.documentElement.clientWidht;}
            if (!clientWidth) {clientWidth = document.body.clientWidth;}
            var clientHeight = window.innerHeight;
            if (!clientHeight) {clientHeight = document.documentElement.clientHeight;}
            if (!clientHeight) {clientHeight = document.body.clientHeight};
        
            this.editPanel.style.left = (clientWidth - parseInt(this.editPanel.offsetWidth)) / 2;
            this.editPanel.style.top = (clientHeight - parseInt(this.editPanel.offsetHeight)) / 2;
        }
        else {
            this.editPanel.style.display = 'none';
        }
    }
    //////// 追加 //////////////////////////////////////////////////
    ,appendSchedule:function(obj, d)
    {
        this.schEdit = new Schedule();
        if (d) {
            this.schEdit.scheduleDate = d;
        }
        this.showEditPanel(true, 'スケジュール追加', this.schEdit);
    }
    //////// 編集 //////////////////////////////////////////////////
    ,editSchedule:function(obj, schedule)
    {
        this.schEdit = schedule;
        this.showEditPanel(true, 'スケジュール編集', this.schEdit);
    }
    //////// 決定 //////////////////////////////////////////////////
    ,editSubmit:function()
    {
        this.showEditPanel(false);

        str = txtDate.value;
        str.match(/([\d]{4,4})[\/\-]([\d]{1,2})[\/\-]([\d]{1,2})/);
        year = parseInt(RegExp.$1);
        month = parseInt(RegExp.$2) - 1;
        day = parseInt(RegExp.$3);
        if (year && month && day) {
            this.schEdit.scheduleDate = new Date(year, month, day);
        }
        
        this.schEdit.scheduleBody = this.txtBody.value.XMLEncode().replace(/\r/g, '').replace(/\n/g, '<br />');
        this.post(this.schEdit, 'save');
    }
    //////// 戻る //////////////////////////////////////////////////
    ,editCancel:function()
    {
        this.showEditPanel(false);
    }
    //////// 削除 //////////////////////////////////////////////////
    ,editDelete:function()
    {
        if (window.confirm('本当にこの予定を削除してよろしいですか？')) {
            this.showEditPanel(false);
            this.post(this.schEdit, 'del');
        }
    }
    //////// D&D //////////////////////////////////////////////////
    ,mousedown:function(e)
    {
        if (this.dragging) {return false;}
        this.dragging = true;
        body = document.getElementsByTagName('body').item(0);
        body.setAttribute('unselectable', 'on'); //文字選択禁止
        document.body.setAttribute('unselectable', 'on'); //文字選択禁止
    
        MX = Event.pointerX(e);
        MY = Event.pointerY(e);
        this.dragStartX = MX;
        this.dragStartY = MY;
        this.oldLeft = parseInt(this.editPanel.style.left);
        this.oldTop = parseInt(this.editPanel.style.top);
    }
    ,mousemove:function(e)
    {
        if (!this.dragging) {return false;}

        MX = Event.pointerX(e);
        MY = Event.pointerY(e);
        this.editPanel.style.left = this.oldLeft + (MX - this.dragStartX) + 'px';
        this.editPanel.style.top = this.oldTop + (MY - this.dragStartY) + 'px';
    }
    ,mouseup:function(e)
    {
        if (!this.dragging) {return false;}
        this.dragging = false;
        body = document.getElementsByTagName('body').item(0);
        body.removeAttribute('unselectable'); //文字選択禁止
        document.body.removeAttribute('unselectable'); //文字選択禁止

        MX = Event.pointerX(e);
        MY = Event.pointerY(e);
        this.editPanel.style.left = this.oldLeft + (MX - this.dragStartX) + 'px';
        this.editPanel.style.top = this.oldTop + (MY - this.dragStartY) + 'px';
    }
}
//**********************************************************************
//schedule
//**********************************************************************
var Schedule = Class.create();
Schedule.prototype = {
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //コンストラクタ
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    initialize: function()
    {
        this.scheduleNo = 0;
        this.scheduleDate = new Date();
        this.scheduleBody = '';
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //XML
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //////// ロード //////////////////////////////////////////////////
    ,load: function(node)
    {
        if (!node) {return false;}

        var schDate = node.getAttribute('schedule_date');
        var tokens = schDate.split('-');
        var d = new Date(Number(tokens[0]), Number(tokens[1]) - 1, Number(tokens[2]));

        var schedule = new Object();
        this.scheduleNo = parseInt(node.getAttribute('schedule_no'));
        this.scheduleDate = d;
        this.scheduleBody = node.getAttribute('schedule_body');
        
        return true;
    }
    //////// MXL文字列生成 //////////////////////////////////////////////////
    ,toXmlString:function()
    {
        var s = '';
        d = this.scheduleDate.getFullYear() + '-' + (this.scheduleDate.getMonth() + 1) + '-' + this.scheduleDate.getDate();
        
        s += '<schedule';
        
        s += ' schedule_no="' + this.scheduleNo + '"';
        s += ' schedule_date="' + d + '"';
        s += ' schedule_body="' + this.scheduleBody.XMLEncode() + '"';
        
        s += ' />';
        s += "\n";
        
        return s;
    }
}
