﻿/// <reference path="../extjs_intellisense.js" />

//工具类，使用Util的命名空间，方便管理
var Util = new Object();
//获取http header里面的UserAgent，浏览器信息
Util.getUserAgent = navigator.userAgent;
//是否是Gecko核心的Browser，比如Mozila、Firefox 
Util.isGecko = Util.getUserAgent.indexOf("Gecko") != -1;
//是否是Opera 
Util.isOpera = Util.getUserAgent.indexOf("Opera") != -1;
Util.getOffset = function (el, isLeft) {
    var retValue = 0;
    while (el != null) {
        retValue += el["offset" + (isLeft ? "Left" : "Top")];
        el = el.offsetParent;
    }
    return retValue;
};
// 将一个function（参数中的funcName是这个fuction的名字）绑定到一个element上，并且以这个element的上下文运行，其实是一种继承，这个可以google些文章看看 
Util.bindFunction = function (el, fucName) {
    return function () {
        return el[fucName].apply(el, arguments);
    };
};
Util.re_calcOff = function (el) {
    for (var i = 0; i < Util.dragArray.length; i++) {
        var ele = Util.dragArray[i];
        ele.elm.pagePosLeft = Util.getOffset(ele.elm, true);
        ele.elm.pagePosTop = Util.getOffset(ele.elm, false);
    }
    var nextSib = el.elm.nextSibling;
    while (nextSib) {
        nextSib.pagePosTop -= el.elm.offsetHeight;
        nextSib = nextSib.nextSibling;
    }
};

//隐藏Google Ig中间那个table，也就是拖拽的容器，配合show一般就是刷新用，解决一些浏览器的怪癖
Util.hide = function () {
    Util.rootElement.style.display = "none";
};
//显示Google Ig中间哪个table,解释同上
Util.show = function () {
    Util.rootElement.style.display = "";
};

//移动时显示的占位虚线框
ghostElement = null;
//获取这个虚线框,通过dom动态生成
getGhostElement = function () {
    if (!ghostElement) {
        ghostElement = document.createElement("DIV");
        ghostElement.className = "moduleBox";
        ghostElement.backgroundColor = "";
        ghostElement.style.border = "2px dashed #aaa";
        ghostElement.innerHTML = "&nbsp;";
    }
    return ghostElement;
};

//初始化可以拖拽的Element的函数，与拖拽无关的我去掉了
function draggable(el) {
    //公用的开始拖拽的函数
    this._dragStart = start_Drag;
    //公用的正在拖拽的函数
    this._drag = when_Drag;
    //公用的拖拽结束的函数
    this._dragEnd = end_Drag;
    //这个函数主要用来进行拖拽结束后的dom处理
    this._afterDrag = after_Drag;
    //是否正在被拖动，一开始当然没有被拖动 
    this.isDragging = false;
    //将这个Element的this指针注册在elm这个变量里面，方便在自己的上下文以外调用自己的函数等，很常用的方法 
    this.elm = el;
    //触发拖拽的Element，在这里就是这个div上显示标题的那个div 
    this.header = document.getElementById(el.id + "_head");    
	//对于有iframe的element拖拽不同，这里检测一下并记录 
    this.hasIFrame = this.elm.getElementsByTagName("IFRAME").length > 0;
    //如果找到了header就绑定drag相关的event 
    if (this.header) {
    	//拖拽时的叉子鼠标指针 
        this.header.style.cursor = "move";
        //将函数绑定到header和element的this上，参照那个函数的说明
        Drag.init(this.header, this.elm);
        //下面三个语句将写好的三个函数绑定给这个elemnt的三个函数钩子上，也就实现了element从draggable继承可拖拽的函数
        this.elm.onDragStart = Util.bindFunction(this, "_dragStart");
        this.elm.onDrag = Util.bindFunction(this, "_drag");
        this.elm.onDragEnd = Util.bindFunction(this, "_dragEnd");
    }
};

// 下面就是draggable里面用到的那4个function 
// 公用的开始拖拽的函数
function start_Drag() {
	//重置坐标，实现拖拽以后自己的位置马上会被填充的效果
    Util.re_calcOff(this);
    //记录原先的邻居节点，用来对比是否被移动到新的位置
    this.origNextSibling = this.elm.nextSibling;
    //获取移动的时候那个灰色的虚线框
    var _ghostElement = getGhostElement();
    //获取正在移动的这个对象的高度
    var offH = this.elm.offsetHeight;
    if (Util.isGecko) {
    	//修正gecko引擎的怪癖吧
        offH -= parseInt(_ghostElement.style.borderTopWidth) * 2;
    }
    //获取正在移动的这个对象的宽度
    var offW = this.elm.offsetWidth;
    //获取left和top的坐标
    var offLeft = Util.getOffset(this.elm, true);
    var offTop = Util.getOffset(this.elm, false);
    //防止闪烁，先隐藏
    Util.hide();
    //将自己的宽度记录在style属性里面
    this.elm.style.width = offW + "px";
    //将那个灰框设定得与正在拖动的对象一样高，比较形象
    _ghostElement.style.height = offH + "px";
    //把灰框放到这个对象原先的位置上
    this.elm.parentNode.insertBefore(_ghostElement, this.elm.nextSibling);
    //由于要拖动必须将被拖动的对象从原先的盒子模型里面抽出来，所以设定position为absolute，这个可以参考一下css布局方面的知识
    this.elm.style.position = "absolute";
    //设置zIndex，让它处在最前面一层，当然其实zIndex=100是让它很靠前，如果页面里有zIndex>100的，那……
    this.elm.style.zIndex = 100;
    //由于position=absolute了，所以left和top实现绝对坐标定位，这就是先前计算坐标的作用，不让这个模型乱跑，要从开始拖动的地方开始移动
    this.elm.style.left = offLeft + "px";
    this.elm.style.top = offTop + "px";
    //坐标设定完毕，可以显示了，这样就不会闪烁了
    Util.show();
    //这里本来有个ig_d.G，没搞明白干什么用的，不过没有也可以用，谁知道麻烦告诉我一声，不好意思 
    // 还没有开始拖拽，这里做个记号
    this.isDragging = false;
    return false;
};
//在拖拽时的相应函数，由于绑定到鼠标的move这个event上，所以会传入鼠标的坐标clientX, clientY 
function when_Drag(clientX, clientY) {
	//刚开始拖拽的时候将图层变透明，并标记为正在被拖拽
    if (!this.isDragging) {
        this.elm.style.filter = "alpha(opacity=70)";
        this.elm.style.opacity = 0.7;
        this.isDragging = true;
    }
    //被拖拽到的新的column（当然也可以是原来那个）
    var found = null;
    //最大的距离，可能是防止溢出或者什么bug 
    var max_distance = 100000000;
    //遍历所有的可拖拽的element，寻找离当前鼠标坐标最近的那个可拖拽元素，以便后面插入
    for (var i = 0; i < Util.dragArray.length; i++) {
        var ele = Util.dragArray[i];
        //利用勾股定理计算鼠标到遍历到的这个元素的距离
        var distance = Math.sqrt(Math.pow(clientX - ele.elm.pagePosLeft, 2) + Math.pow(clientY - ele.elm.pagePosTop, 2));
        //自己已经浮动了，所以不计算自己的
        if (ele == this) {
            continue;
        }
        //$("resu").value += ele.elm.nextSibling?ele.elm.nextSibling.id+"a":ele.elm.id+"b";//+$("item"+ele.elm.id.split('_')[1]).innerHTML;
        //如果计算失败继续循环
        if (isNaN(distance)) {
            continue;
        }
        //如果更小，记录下这个距离，并将它作为found 
        if (distance < max_distance) {
            max_distance = distance;
            found = ele;
        }
    }
    //准备让灰框落脚
    var _ghostElement = getGhostElement();
    //如果找到了另外的落脚点 
	//-----------------隐藏内容
	$('#' + this.elm.id + '_content').hide();
	
    if (found != null && _ghostElement.nextSibling != found.elm) {
        var index = this.elm.id.indexOf("_");
        var elmId = this.elm.id.substr(index + 1);
        var pid = found.elm.parentNode.id;
//        if((elmId == "6" || elmId == "2" || elmId == "3") && pid != "col_2"){   //  主人动态、好友新鲜事、留言板只能放在中间的模块中
//            return;
//        }     
        if(elmId == "6" && pid != "col_2")//留言板只能放在中间的模块中
        {
            return;
        }
    	//找到落脚点就先把灰框插进去，这就是我们看到的那个灰框停靠的特效，有点像吸附的感觉，哈哈
        found.elm.parentNode.insertBefore(_ghostElement, found.elm);
        if (Util.isOpera) {
        	//Opera的现实问题，要隐藏/显示后才能刷新出变化
            document.body.style.display = "none";
            document.body.style.display = "";
        }
    }
};
//拖拽完毕 
function end_Drag() {
	//拖拽完毕后执行后面的钩子，执行after_Drag()，
	//如果布局发生了变动了就记录到远程服务器，保存你拖拽后新的布局顺序
    if (this._afterDrag()) {
        //remote call to save the change
        //-------------------------------------------------
        //showTip('小提示:您已经改变了布局<br /><input type="button" class="btn" onclick="saveStyle();" value="保存" />&nbsp;<input type="button" class="btn" onclick="hideTip();" value="取消" />');
    }
    return true;
};
//拖拽后的执行钩子
function after_Drag() {
    //------------------显示内容
    $('#' + this.elm.id + '_content').show();
    
    var returnValue = false;
    //防止闪烁
    Util.hide();
    //把拖拽时的position=absolute和相关的那些style都消除
    this.elm.style.position = "";
    this.elm.style.width = "";
    this.elm.style.zIndex = "";
    this.elm.style.filter = "";
    this.elm.style.opacity = "";
    //获取灰框
    var ele = getGhostElement();
    //如果现在的邻居不是原来的邻居了
    if (ele.nextSibling != this.origNextSibling) {
    	//把被拖拽的这个节点插到灰框的前面
        ele.parentNode.insertBefore(this.elm, ele.nextSibling);
        //标明被拖拽了新的地方
        returnValue = true;
    }
    //移除灰框，这是这个灰框的生命周期应该就结束了 
    ele.parentNode.removeChild(ele);
    //修改完毕，显示
    Util.show();
    if (Util.isOpera) {
    	//Opera的现实问题，要隐藏/显示后才能刷新出变化
        document.body.style.display = "none";
        document.body.style.display = "";
    }
    return returnValue;
};
//可拖拽Element的原形，用来将event绑定到各个钩子，这部分市比较通用的，netvibes也是基本完全相同的实现 
// 这部分推荐看dindin的这个，也会帮助理解，http://www.jroller.com/page/dindin/?anchor=pro_javascript_12
var Drag = {
	//对这个element的引用，一次只能拖拽一个Element 
	obj:null, 
	//element是被拖拽的对象的引用，elementHeader就是鼠标可以拖拽的区域
	init:function (elementHeader, element) {
		//将start绑定到onmousedown事件，按下鼠标触发start 
    	elementHeader.onmousedown = Drag.start;
    	//将element存到header的obj里面，方便header拖拽的时候引用
	    elementHeader.obj = element;
	    //初始化绝对的坐标，因为不是position=absolute所以不会起什么作用，但是防止后面onDrag的时候parse出错了 
	    if (isNaN(parseInt(element.style.left))) {
	        element.style.left = "0px";
	    }
	    if (isNaN(parseInt(element.style.top))) {
	        element.style.top = "0px";
	    }
	    //挂上空Function，初始化这几个成员，在Drag.init被调用后才帮定到实际的函数，可以参照draggable里面的内容 
	    element.onDragStart = new Function();
	    element.onDragEnd = new Function();
	    element.onDrag = new Function();
	},
	//开始拖拽的绑定，绑定到鼠标的移动的event上
	start:function (event) {
	    var element = Drag.obj = this.obj;
	    //解决不同浏览器的event模型不同的问题
	    event = Drag.fixE(event);
	    //看看是不是左键点击
	    if (event.which != 1) {
	    	// 除了左键都不起作用 
	        return true;
    	}
    	//参照这个函数的解释，挂上开始拖拽的钩子
	    element.onDragStart();
	    //记录鼠标坐标
	    element.lastMouseX = event.clientX;
	    element.lastMouseY = event.clientY;
	    //将Global的event绑定到被拖动的element上面来
	    document.onmouseup = Drag.end;
	    document.onmousemove = Drag.drag;
	    return false;
	}, 
	//Element正在被拖动的函数
	drag:function (event) {
		//解决不同浏览器的event模型不同的问题
	    event = Drag.fixE(event);
	    //看看是不是左键点击
	    if (event.which == 0) {
	    	//除了左键都不起作用 
	        return Drag.end();
    	}
    	//正在被拖动的Element 
	    var element = Drag.obj;
	    //鼠标坐标
	    var _clientX = event.clientY;
	    var _clientY = event.clientX;
	    //如果鼠标没动就什么都不作 
	    if (element.lastMouseX == _clientY && element.lastMouseY == _clientX) {
	        return false;
	    }
	    //刚才Element的坐标
	    var _lastX = parseInt(element.style.top);
	    var _lastY = parseInt(element.style.left);
	    //新的坐标
	    var newX, newY;
	    //计算新的坐标：原先的坐标+鼠标移动的值差
	    newX = _lastY + _clientY - element.lastMouseX;
	    newY = _lastX + _clientX - element.lastMouseY;
	    //修改element的显示坐标
	    element.style.left = newX + "px";
	    element.style.top = newY + "px";
	    //记录element现在的坐标供下一次移动使用
	    element.lastMouseX = _clientY;
	    element.lastMouseY = _clientX;
	    //参照这个函数的解释，挂接上Drag时的钩子
	    element.onDrag(newX, newY);
	    return false;
	},
	//Element正在被释放的函数，停止拖拽
	end:function (event) {
		//解决不同浏览器的event模型不同的问题
	    event = Drag.fixE(event);
	    //解除对Global的event的绑定
	    document.onmousemove = null;
	    document.onmouseup = null;
	    //先记录下onDragEnd的钩子，好移除obj 
	    var _onDragEndFuc = Drag.obj.onDragEnd();
	    //拖拽完毕，obj清空 
	    Drag.obj = null;
	    return _onDragEndFuc;
	}, 
	//解决不同浏览器的event模型不同的问题
	fixE:function (ig_) {
	    if (typeof ig_ == "undefined") {
	        ig_ = window.event;
	    }
	    if (typeof ig_.layerX == "undefined") {
	        ig_.layerX = ig_.offsetX;
	    }
	    if (typeof ig_.layerY == "undefined") {
	        ig_.layerY = ig_.offsetY;
	    }
	    if (typeof ig_.which == "undefined") {
	        ig_.which = ig_.button;
	    }
    	return ig_;
	}
};

//下面是初始化的函数了，看看上面这些东西怎么被调用 
// window.onload = _IG_initDrag(document.getElementById("t_1"));
var _IG_initDrag = function (el) {
	//column那个容器，在google里面就是那个table布局的tbody，netvibes用的<div>	
    Util.rootElement = el;
    //这个tbody的行
    Util._rows = Util.rootElement.tBodies[0].rows[0];
    //列，google是3列，其实也可以更多 
    Util.column = Util._rows.cells;
    //用来存取可拖拽的对象
    Util.dragArray = new Array();
    var counter = 0;
    for (var i = 0; i < Util.column.length; i++) {
        var ele = Util.column[i];
        for (var j = 0; j < ele.childNodes.length; j++) {
            var ele1 = ele.childNodes[j];            
//            if (ele1.tagName == "DIV" || ele1.tagName == "TABLE") {
//                Util.dragArray[counter] = new draggable(ele1);
//                //
//                counter++;
//            }
            if(ele1.tagName == "DIV")
            {
                Util.dragArray[counter] = new draggable(ele1);
                counter++;
            }
//            else if(ele1.tagName == "TABLE")
//            {
//                var ele2 = ele1.childNodes[0];
//                if(ele2.tagName == "TBODY")
//                {
//                    for(var k = 0; k < ele2.childNodes.length; k++)
//                    {
//                        var ele3 = ele2.childNodes[k];
//                        if(ele3.tagName == "TR")
//                        {
//                            for(var l = 0; l < ele3.childNodes.length; l++)
//                            {
//                                var ele4 = ele3.childNodes[l];
//                                if(ele4.tagName == "TD")
//                                {                                    
//                                    var ele5 = ele4.childNodes[0];
//                                    if(ele5 && ele5.tagName == "DIV")
//                                    {
//                                        Util.dragArray[counter] = new draggable(ele5);
//                                        counter++;
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//            }
        }
    }
    
};

function menuClose(id)
{
    $("#menu_" + id).hide();
    $("#menuList_" + id).attr("checked", false);
}

function myClose(id)
{    
    $("#module_" + id).hide();
    $("#moduleList_" + id).attr("checked", false);
    //changeModuleStatus(id)
}
function saveMenu()
{
   //column那个容器
	if(typeof UtilContent == "undefined")
	{
	    UtilContent = {};
	}
	
    UtilContent.rootElement = document.getElementById('menuTable');
    UtilContent._rows = UtilContent.rootElement.tBodies[0].rows[0];
    UtilContent.column = UtilContent._rows.cells;
    var newStyle = "";
    for (var i = 0; i < UtilContent.column.length; i++) {
        var ele = Util.column[i];
        for (var j = 0; j < ele.childNodes.length; j++) {
            var ele1 = ele.childNodes[j];
            if (ele1.tagName == "DIV" && ele1.id.substr(0, 2) != "no" && ele1.style.display != "none") {
                if (ele1.id.split('_')[1]) {
                    newStyle += ele1.id.split('_')[1] + ",";
                }
            }
        }
        if (newStyle.length > 0) {
            newStyle = newStyle.substring(0, newStyle.length - 1);
        }
    }    
    hideTip();
    var param = {};
    param.newStyle = newStyle;   
    $.post('/m/ajax?action=SaveUserMenu',param,function(data){
        data = data.split('{$}');
        if(data.length>0)
        {
            showTip(data[1]);
            if(data[0]=="1")
            {
                window.setTimeout(function(){location.href = '/' + $("#userId").val() + "/" + Math.ceil(Math.random()*2008);},2000);
            }
        }
        else
        {
            showTip(data);
        }
    }); 
}
function saveStyle()
{
    //column那个容器
	if(typeof UtilContent == "undefined")
	{
	    UtilContent = {};
	}
	
    UtilContent.rootElement = document.getElementById('bodyTable');
    UtilContent._rows = UtilContent.rootElement.tBodies[0].rows[0];
    UtilContent.column = UtilContent._rows.cells;
    var newStyle = "";
    for (var i = 0; i < UtilContent.column.length; i++) {
        var ele = Util.column[i];
        for (var j = 0; j < ele.childNodes.length; j++) {
            var ele1 = ele.childNodes[j];
            if (ele1.tagName == "DIV"&&ele1.id.substr(0,2) != "no"&& ele1.style.display !="none") {
                if(ele1.id.split('_')[1])
                {
                    newStyle += ele1.id.split('_')[1];
                }
            }
            newStyle += ",";
        }
        newStyle +="_";
    }
    hideTip();
    var param = {};
    param.newStyle = newStyle;
    param.newLayout = $("#layoutIdNew").val();
    param.newSkin = $("#layoutSkinNew").val();
    $.post('/m/ajax?action=SaveUserStyle',param,function(data){
        data = data.split('{$}');
        if(data.length>0)
        {
            showTip(data[1]);
            if(data[0]=="1")
            {
                window.setTimeout(function(){location.href = '/' + $("#userId").val() + "/" + Math.ceil(Math.random()*2008);},2000);
            }
        }
        else
        {
            showTip(data);
        }
    });
}
function showTip(msg)
{
    $('div.control').html(msg);
}

function hideTip()
{
    //$('#tiptosave').animate({'left':-500},'hide');
}
$(document).ready(function(){
    if(document.getElementById('bodyTable'))
    {
        _IG_initDrag(document.getElementById('bodyTable'));
    }
    if(document.getElementById('menuTable'))
    {
        _IG_initDrag(document.getElementById('menuTable'));
    }
    //alert($('div.control').size())
    $('div.control').addClass('saveTip').show();
    $(document).scroll(function(){
        $('div.control').css('top', document.documentElement.scrollTop + 'px');
    });
});