/** 
@version $Id: extend_html.js 130 2010-09-29 10:03:56Z jax.hu $

element [延伸屬性]{所有元素共用}
    removeDelay="sec"  {設定幾秒鐘後自動[移除]此元素}
    pulsate="sec"  {設定幾秒鐘後自動結束元素[閃爍]}
    
    
input,textarea [延伸屬性]
    emptyText="為空預設提示" {設定當輸入匡為空時的文字提示} 


table,tbody [延伸樣式] 
    class="Sortable"{表格排序}
    
    class="SortHandle"{表格排序的把手,必要的選項設定}



form 中的[延伸屬性]及[延伸樣式]
    tr
        class="NotNull" {檢查區塊內的元素是否有選項值}
        
    input   
        format="" {表單送出前的格式檢查,但不會檢查為空}    
        	'tel':電話
        	'mobile':行動電話
        	'email':電子信箱
        	'url':網路連結
        	'date':日期
        	'time':時間        
        
        jtype="" {資料輸入時的輔助}
          (基本格式輸入)
            'uint':無符號整數
            'int':整數
            'float':浮點數
            'id':帳號格式
            'alnum':保留字母和数字及底線

          (輔助日期輸入)
            'date':選擇日期
            'start_date':選擇起始日期
            'end_date':選擇結束日期
            'birth':選擇出生日期
                
          (UI 呈現)
            'search_keyword':
            'highlight_keyword':
                
            'deff_new':
            'deff_old':
        
*/



/*XXX : Show Object Element ( 顯示物件的元素 ) */
function var_dump(variable,unWindow){
    var i, outTemp = [], eName, eValue;

    for (i in variable) {
        /* 加入例外處裡 */
        try {
            /* 設定元素數值的樣式 */
            eValue=variable[i].toString().replace("function",'<b style="color:#0000ff;">function</b>');
            /* 將資料串接在一起 */
            outTemp.push('<b style="color:#770077;">'+i+'</b> = '+eValue);
        }catch (e) {
            /* 處理例外事件的訊息 */
            eName = (e + '').replace(/" /g, '"<br/>');
			outTemp.push(eName.fontcolor('red'));
        }
    }

    /* 設定顯示的視窗 */
    i=window.open("","","width=450,height=550,scrollbars=yes,resizable=yes");
    /* 將資料加入視窗的文件中，並設定字體定寬及大小 */
    i.document.body.innerHTML = outTemp.join("<hr/>").fixed().fontsize(2);
    /* 設定顯示視窗的標題 */
    i.document.title = 'Show Object Element';
    /* 讓顯示視窗取得焦點 */
    i.focus();
}


/*文字差異比對*/
function difference(insStr,delStr){
	insStr = (insStr||'').split('');
	delStr = (delStr||'').split('');
	
	var insLength=insStr.length, delLength=delStr.length, dynamic=[], i, j;
	for(i=0;i<=insLength;i++){dynamic[i]=[];dynamic[i][0]=0;}
	for(j=1;j<=delLength;j++){dynamic[0][j]=0;}
	
	/*Longest Common Subsequence*/
	for(i=1; i<=insLength; i++){
		for(j=1; j<=delLength; j++){
			if(insStr[i-1]==delStr[j-1]){
				dynamic[i][j]=dynamic[i-1][j-1]+1;
			}else if(dynamic[i][j-1] > dynamic[i-1][j]){
				dynamic[i][j]=dynamic[i][j-1];
			}else{
				dynamic[i][j]=dynamic[i-1][j];
			}
		}
	}
	
	/*標註共同部分序列*/
	i=insLength; j=delLength;
	var insMark=[], delMark=[];
	insMark[i]=delMark[j]='Y';
	while(i>0 && j>0){
		if(dynamic[i][j]==dynamic[i-1][j]){
			i--;
		}else if(dynamic[i][j]==dynamic[i][j-1]){
			j--;
		}else{
			i--;j--;
			insMark[i]=delMark[j]=true;
		}
	}

	/*加量有差異的字串*/
	for(i=1,j=0; i<=insLength; i++){
		if(insMark[i-1]==insMark[i]){insStr[j]+=insStr[i]; continue;}
		if(!insMark[i-1]){insStr[j] = '<ins>'+insStr[j]+'</ins>';}
		insStr[++j]=insStr[i];
	}
	insStr.length=j;
	
	for(i=1,j=0; i<=delLength; i++){
		if(delMark[i-1]==delMark[i]){delStr[j]+=delStr[i]; continue;}
		if(!delMark[i-1]){delStr[j] = '<del>'+delStr[j]+'</del>';}
		delStr[++j]=delStr[i];
	}
	delStr.length=j;
	
	delete dynamic,insMark,delMark;
	return {'ins':insStr.join(''),'del':delStr.join('')};
}






jQuery(function($) {
	
	/*設定日曆選擇的預設語言*/    
	$.datepicker.setDefaults($.extend($.datepicker.regional['zh-TW'],{ 
		showMonthAfterYear: true,
		changeMonth: true,      
		changeYear: true,      
	    dateFormat:'yy-mm-dd',           
	    showOn:'both', // 'button',      
	    buttonImage: '/pub/ui_style/img/calendar-select.png',      
	    buttonImageOnly: true, 
	    buttonText:'選擇日期',
		firstDay:0
	}));



/**=(Twinkle 全頁面閃爍)===============================================*/
//    setInterval(function(){ $(document.body).toggleClass('HideOn'); },500);


/**=(元素延遲移除)===============================================*/
    $('[removeDelay]').each(function(){
        var $el=$(this);    
        var delayTime=parseInt($el.attr('removeDelay'));
        if(delayTime){
            delayTime*=1000;
            setTimeout(function(){ $el.remove(); }, delayTime);
        }
    });
	
/**=(元素閃爍)===============================================*/
    $('[pulsate]').each(function(){
        var $el=$(this);    
		$el.show('pulsate',{times:parseInt($el.attr('pulsate'))},600);
    });
 
 
 
/**=(為空預設文字)===============================================*/
    $('[emptyText]').focus(function(){
        var $el = $(this);    
		if($.trim($el.val())!=$el.attr('emptyText')){return;}
        $el.val('').css("color","");
    }).blur(function(){
        var $el = $(this);    
		if($.trim($el.val())!='' && $.trim($el.val())!=$el.attr('emptyText')){return;}
		$el.val($el.attr('emptyText')).css("color","#999999");
    }).trigger('blur');
	
	

/**=(元素樣式切換)===============================================*/
    $("[toggle]").css('cursor','pointer').click(function(){
        var $el=$(this);
		$($el.attr('expr')).toggleClass($el.attr('toggle')); 
    });
	
	
	
/**=(表格過濾)===============================================*/
    $("[tableFilter]").change(function(){
        var $el=$(this);
		var tableId=$el.attr('tableFilter');
		
        var filter = $el.find("input[name='filter']:checked").map(function(){
			return this.value;
		}).get();		
		
		var tableFilter = $.cookie('tableFilter')||'{}';
		tableFilter = $.evalJSON(tableFilter);

		tableFilter[tableId]=filter;
		$.cookie('tableFilter',$.toJSON(tableFilter),{expires:365});
		
		Style.setTableFilter(tableId,filter);
    });


	
/**=(項目選擇標示)===============================================*/
    $(".Option").change(function(){
		$(this).find("label input:radio, label input:checkbox").each(function(){
			if(this.checked){
		        $(this).parent('label').addClass('Selected');/*label 父節點*/ 
			}else{
		        $(this).parent('label').removeClass('Selected');/*label 父節點*/ 
			}
	    });
	}).trigger('change');
	
	
	
/**=(選項選擇)===============================================*/
	/*雙擊點選控制*/            
    $(".Selector label").dblclick(function(){
		$el = $(this);
		/*加入選項*/
		if($el.parent('div').hasClass('NotSelected')){
			$el.addClass("Selected").find("input:eq(0)").attr("disabled",false);
			$el.parents('.Selector:eq(0)').find("div.Selected:eq(0)").append($el);
			
		/*移除選項*/	
		}else{
			$el.removeClass("Selected").find("input:eq(0)").attr("disabled",true); 
			$el.parents('.Selector:eq(0)').find("div.NotSelected:eq(0)").append($el); 
		}
    });
    /*搜尋*/
	$(".Selector input.SearchInput").keyup(function(){
		var key = $.trim(this.value);
		var $labels = $(this).parents('.Selector:eq(0)').find('div.NotSelected label');	
		if(key){
			$labels.hide().filter(":contains('"+key+"')").show(); 
		}else{
			$labels.show(); 
		}
    });
    /*資料排序*/
	$(".Selector div.Selected").sortable({opacity: 0.7,axis: 'y'});




	
/**=(Ajax 資料排序)===============================================*/
	$(".Sortable").sortable({ 
        handle: '.SortHandle', 
        opacity: 0.7,
        axis: 'y', 
        update: function() {
            var $el = $(this); /*取得排序的 tbody*/
            var sequence = $el.find("[name^='sequence']").filter(function(){
    			return this.name && !this.disabled && 
    				(this.checked || /text|hidden|password/i.test(this.type));
    		});

            $.ajax({ /*Ajax 送出設定*/
                type: "POST",
                url: './sort',
                data: $.param(sequence),
				beforeSend: function(){
		            $el.sortable('disable'); /*暫時關閉排序功能*/
		        },				
                success: function(){
                    $el.sortable('enable'); /*重新啟動排序*/
                    /*排序 Id*/
                    var sortId = sequence.map(function(){ return this.value; }); 
                    sortId.sort(function(a,b){return a < b;}); 
                    /*與後端同步*/
                    sequence.each(function(i){ this.value = sortId[i]; });
                },
                error: function(){
                    StatusMsg.error('排序失敗請[<a href="JavaScript:document.location.reload();">重新整理</a>]頁面');
                }
            });
                        
        }
    }).disableSelection();





/**=(表單自動儲存)===============================================*/
    $('[autoSaveTime]').each(function(){
        var $el=$(this);    
		$el.attr('datum',$el.serialize());
		$el.bind("autoSave", function(){
	        var $el=$(this);    
			var formData=$el.serialize();
			if($el.attr('datum')==formData){return;}
		    
		    $.ajax({ /*Ajax 送出設定*/
		        type: "POST", url: './draft', data: formData,
				beforeSend: function(){
					$btn.attr("disabled",true).find('.Icon').addClass('Wait'); 
					StatusMsg.wait('自動儲存中...');
		        },
		        success: function(msg){
					$el.attr('datum',this.data);
					StatusMsg.alert(msg);
		        },
		        error: function(e){
					StatusMsg.error(e.responseText);
		        },
				complete:function(){
					$btn.attr("disabled",false).find('.Icon').removeClass('Wait'); 
		        }
		    });
		}); 
		
		var $btn=$el.find('.AutoSaveAction:eq(0)');
		$btn.click(function(){
			if($el.attr('datum')==$el.serialize()){
				StatusMsg.alert('資料沒有變更，不需要儲存!'); return;
			}
			$el.trigger('autoSave');
		});

        var delayTime=parseInt($el.attr('autoSaveTime'));
        if(delayTime){
            delayTime*=1000;
            setInterval(function(){ $el.trigger('autoSave'); },delayTime);
        }
    });


	
	
/**=(顯示輸入的字串長度)===============================================*/
    $(".ShowLength").change(function(){
        var length=$(this).find(".Input").val().length;    
		$(this).find(".Total").text(length);
    }).trigger('change');

	
	
	
/**=(文字差異比對)===============================================*/
    $(".DiffHighlight tr").each(function(){
		$ins=$(this).find('td.DiffNew:eq(0)');
		$del=$(this).find('td.DiffOld:eq(0)');
		diff = difference($ins.html(), $del.html());
		$ins.html(diff.ins); $del.html(diff.del);
    });


        
/**=(表單送出前格式檢查)===============================================*/
    $("form").submit(function(){
        var isPass = true;

        /**=(為空檢查)===============================================*/
        $('.NotNull',this).each(function(){
            var $el=$(this);    

            var value =  $('input,textarea,select',this).filter(function(){
    			return this.name && !this.disabled && 
    				(this.checked || /select|textarea/i.test(this.nodeName) ||
    					/text|hidden|password|search/i.test(this.type));
    		});
            
            /*處理格式錯誤的顯示*/
            if(value[0]===undefined || value[0].value==''){
                $el.addClass('Error');
                
                if(isPass && value[0]!==undefined){
                    $(value[0]).focus();
                }
                isPass = false;            
            }else{
				$el.removeClass('Error');
			}
        });

        
        /**=(輸入格式檢查)===============================================*/
        $('[format]',this).each(function(){
            var $el=$(this);
            var isError = false;
            
            /*資料為空不檢查格式*/
            if($el.val()==''){return;}
            
            /*依分類檢查下列格式*/
            switch($el.attr('format')){
                case 'tel':/*電話*/
                    var value = $el.val();
                    
                    var match = value.match(/[0-9]{2,}-[0-9]{7,}/);
                    isError = (match===null || match[0]!=value); break;
                    
                case 'mobile':/*行動電話*/
                    var value = $el.val();
                    
                    var match = value.match(/09[0-9]{8,}/);
                    isError = (match===null || match[0]!=value); break;
                    
                case 'email':/*電子信箱*/
                    var value = $el.val();
                    
                    var match = value.match(/([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})/);
                    isError = (match===null || match[0]!=value); break;
                                        
                case 'url':/*網路連結*/
                    var value = $el.val();
                    var match = value.match(/[a-zA-Z]+:\/\/[a-zA-Z0-9]+.*$/);
                    
                    isError = (match===null || match[0]!=value); break;
                                        
                case 'date':/*日期*/
                    var value = $el.val().replace(/-0*/g,'/');
                    var acc = new Date(value);
                    var match = acc.getFullYear()+"/"+ (acc.getMonth()+1) +"/"+ acc.getDate();
                    
                    isError = (value!=match); break;                    
               
                case 'time':/*時間*/
                    var value = $el.val().split(':');
                    var acc = new Date();
                    acc.setHours(value[0],value[1]);
                    value = (parseInt(value[0])||99)+":"+(parseInt(value[1])||99);
                    var match = acc.getHours()+":"+acc.getMinutes();
                    
                    //isError = ((acc.getHours()+'')=='NaN' || (acc.getMinutes()+'')=='NaN' || value!=match); break;
                    isError = (value!=match); break;
            }

            /*錯誤旗標*/
            var flag = $el.parents('tr:eq(0)');/*tr 父節點*/ 
            if(!flag){flag = this;}
            flag = $(flag).removeClass('Error');

            /*處理格式錯誤的顯示*/
            if(isError){
                flag.addClass('Error');
                if(isPass){
                    $el.focus();
                    isPass = false;            
                }
            }
            
                        
        });
        
        return isPass;
    });     
    
    
/**=(輸入的格式類型)===============================================*/
    $("form [jtype]").each(function(){
        var $el=$(this);
        switch($el.attr('jtype')){
        /**=(限制輸入)===============================================*/
            case 'uint':/*無符號整數*/
                $el.keyup(function(){
                	match = this.value.match(/(0|[1-9][0-9]*)/);
                	this.value = match? match[0] : '';
                }) ;
                break;
            case 'int':/*整數*/
                $el.keyup(function(){
                	match = this.value.match(/0|(-?([1-9][0-9]*)?)/);
                	this.value = match? match[0] : '';
                }) ;
                break;
            case 'float':/*浮點數*/
                $el.keyup(function(){
                	match = this.value.match(/(-?(0|[1-9][0-9]*)?)(\.[0-9]*)?/);
                	this.value = match? match[0] : '';
                });
                break;
            case 'id':/*帳號格式*/
                $el.keyup(function(){
                	match = this.value.match(/[a-z][a-z0-9_\.]*/);
                	this.value = match? match[0] : '';
                });
                break;
            case 'alnum':/*保留字母和数字及底線*/
                $el.keyup(function(){
                	match = this.value.match(/[a-z0-9_]*/i);
                	this.value = match? match[0] : '';
                });
                break;


        /**=(輔助日期輸入)===============================================*/
            case 'date':/*選擇日期*/
                $el.css("width","6em")
                .attr("autocomplete","off")
                //.val(this.value || ($.datepicker.formatDate('yy-mm-dd', new Date())))
                .datepicker();
                break;
            case 'start_date':/*選擇起始日期*/
                $el.css("width","6em")
                .attr("autocomplete","off")
                .val(this.value || ($.datepicker.formatDate('yy-mm-dd', new Date())))
                .datepicker({
                    onSelect: function(dateText){
        				var date = $.datepicker.parseDate('yy-mm-dd', dateText);
        				$("form [jtype='end_date']").datepicker('option',{minDate:date});
                    }
                });
                break;
            case 'end_date':/*選擇結束日期*/
                $el.css("width","6em")
                .attr("autocomplete","off")
                .val(this.value || ($.datepicker.formatDate('yy-mm-dd', new Date())))
                .datepicker({
                    onSelect: function(dateText){
        				var date = $.datepicker.parseDate('yy-mm-dd', dateText);
        				$("form [jtype='start_date']").datepicker('option',{maxDate:date});
                    }
                });
                break;
        /**=(輔助時間輸入)===============================================*/
            case 'time':/*選擇時間*/
                $el.css("width","4em")
                .attr("autocomplete","off");
                break;				
        }
        
        
    }); 
    
	/*移至第一個錯誤點*/
//	$('form .Mark.Error:eq(0)').focus();


	/*初始化表格過濾*/  
	Style.onload();
}); 


//window.onbeforeunload=function(){return"編輯尚未儲存，是否要離開此頁面?";};
$(window).load(function(){
	$("form").submit(function(){
		window.onbeforeunload=null;
	});
});


var Style={
	init:function(){
		/*初始化佈景顏色*/ 
		if(themeColor = $.cookie('theme_color')){
			Style.setTheme(themeColor);
		}
		
		/*初始化背景底圖*/  
		if(bgImage = $.cookie('bg_image')){
			Style.setBackground(bgImage);
		}
	},
	
	onload:function(){
		/*初始化表格過濾*/  
		var tableFilter = $.cookie('tableFilter')||'{}';
		tableFilter = $.evalJSON(tableFilter);
		
		$.each(tableFilter, function(tableId,filter){
			var flag=$("[tableFilter='"+tableId+"']");
			$.each(filter, function(i,value){
				$("input[name='filter'][value='"+value+"']",flag).attr("checked","true");
			});
			Style.setTableFilter(tableId,filter);
		}); 		
	},
	
	/*表格過濾*/  
	setTableFilter:function(tableId,filterList){
		var temp=$.map(filterList, function(value){
			return('#'+tableId+' .'+value);
		}); 
		
		tableId='TableFilter_'+tableId;
		$('#'+tableId).remove();
		$('<style id="'+tableId+'" type="text/css">'+temp.join(', ')+'{display:none;}</style>').appendTo("head"); 
	},
	
	/*佈景顏色*/  
	setTheme:function(color){
		color=color.split(',');
		styleTpl=	'.ShoutboxList .Author a, .ContentTitle {color:/*1*/;}'+
					'a:link, a:visited, a:active, #Navbar a:hover{ color:/*2*/;}'+ 
					'.ListItem:hover{ color:/*2*/ !important;}'+ 
					'a:hover {color:/*1*/;}'+
					'.ContentTitle, .SecDivide {border-color:/*2*/;}'+
					'.Button.Strong{ background-color:/*1*/; background-color:/*1*/ !important;}'+ 
					'.TableList tr:nth-child(even) { background-color:/*1*/;}'+
					'.Button, .SecDivide .Title, .Toolbar, .TableList th, div.PageLinks a:hover {background-color:/*2*/;}'+
					'.TableList tbody tr:hover td {background-color:/*3*/;}';
		//styleTpl='';//TODO 停用布景切換			
					
		styleTpl = styleTpl.replace(/\/\*[0-9]\*\//gi, function(needle){
			switch(needle) {
				case '/*1*/': return color[0];
				case '/*2*/': return color[1];
				case '/*3*/': return color[2];
			}
		});
		$('#ThemeColor').remove();
		$('<style id="ThemeColor" type="text/css">'+styleTpl+'</style>').appendTo("head"); 
	},
	
	/*背景底圖*/  
	setBackground:function(image){
		styleTpl='body{ background-image:url(/pub/ui_style/img/bg//*image*/); }';
		styleTpl = styleTpl.replace(/\/\*image\*\//gi,image);
		$('#BackgroundImage').remove();
		$('<style id="BackgroundImage" type="text/css">'+styleTpl+'</style>').appendTo("head"); 
	}
};
Style.init();





/**訊息處理*/
var StatusMsg={
    timerId:null,
    clear:function(){
        clearTimeout(this.timerId);
        $("#status_msg").empty();
    },
    alert:function(str){
        this.clear();/*清除之前的訊息*/
       
        $el=$('<span class="Msg">'+str+'</span>');
        this.timerId=setTimeout(function(){/*自動移除訊息*/
            $el.remove();
        },10000);
		$el.show('pulsate',{times:4},600);/*閃爍效果*/
        
        $("#status_msg").append($el); /*顯示訊息*/
    },
    error:function(str){
        this.clear();/*清除之前的訊息*/
       
        $el=$('<span class="Error">'+str+'</span>');
		$el.show('pulsate',{times:4},600);/*閃爍效果*/
        
        $("#status_msg").append($el); /*顯示訊息*/
    },
    wait:function(str){
        this.clear();/*清除之前的訊息*/
       
        $el=$('<span class="Wait">'+str+'</span>');
        $("#status_msg").append($el); /*顯示訊息*/
    }
};




/**跳躍至指定錨點*/
function JumpTo(els) {  
	this.els=els;
	this.point=-1;
	
	this.jump=function(i,el){
		var l=this.els.length;
		this.point=(this.point+l+i)%l;
		if(this.els[this.point]){
			el.href = '#'+this.els[this.point].name;
		}else{
			el.href='JavaScript:void(0);';
		}
	};
};	
