//自定义的常用功能函数

Array.prototype.remove = function(index)//删除数组中指定下标的元素,index是下标,扩展Array对象原型
{
	if(isNaN(index) || index>this.length)	return false;

	this.splice(index,1);
}
String.prototype.repeat = function(str,num)//重复指定的str,num次
{
	var _repeatStr = new Array(num+1).join(str);
	
    return this+_repeatStr;
}

/*loadJs动态载入js文件,file是需载入的文件（包含路径）*/
function loadJs(file)
{
	if(typeof(file)=='undefined')	return false;
    var scriptTag = document.getElementById('loadScript');
    var head = document.getElementsByTagName('head').item(0);
    if(scriptTag) head.removeChild(scriptTag);
    script = document.createElement('script');
    script.src = file;
    script.type = 'text/javascript';
    script.id = 'loadScript';
    head.appendChild(script);
}
/*loadCss动态载入ＣＳＳ文件*/
function loadCss(file)
{
	if(typeof(file)=='undefined')	return falsel;
    var head = document.getElementsByTagName('head').item(0);
    css = document.createElement('link');
    css.href = file;
    css.rel = 'stylesheet';
    css.type = 'text/css';
    head.appendChild(css);
}

//进度条
function progress(status,text)
{
	//loadCss('../js/progress/progress.css');//其路径表示的是以嵌入当前js的文件所在的路径表示的，因我的框架都是以当前站点的二级目录开始的，所以应该这样写
	var progressId = '#progress';
	if(typeof(text)=='undefined' || text=='')
	{
		text = '正在处理，请稍等···';
	}
	
	if(typeof(status)=='undefined' || status=='show' || status=='open')
	{
		var h='<div id="progress"><div class="tc-mask"><iframe></iframe></div><div id="progress-bg"><h5>'+text+'</h5><p>如果系统长时间没有反映，请“刷新”下。</p></div></div>';
		$('body').append(h);
	}
	else
	{
		$(progressId).remove();
	}
}

function submitForm()//用于表单区域外的“提交”按钮，id为form的id，如果没有指定，则默认为'tForm'
{
	var id = 'tForm';
	progress('show');//显示进度条
	document.getElementById(id).submit();
}


/**
 * rand 
 * 产生随机数
 * 
 * @access public
 * @return void
 */
function rand()
{
    return ((Math.random()).toString()).substr(2);
}

/**
 * 显示提示信息 
 * 提示信息来源地指定元素的title属性或options指定的信息
 * options={
 *      class:'指定显示信息的提示框的样式表',
 *      msg:'需显示提示信息,没有此属性则自动查找当前对象的title',
 *      offSetX:'提示框水平方向偏移值',offSetY:'垂直水方向偏移值',
 *      action:'add增加错误显示，remove表示删除当前对象错误显示,removeAll表示清除所错误提示，默认为add'
 * }
 *
 * checkbox,radio等元素(响应不易确定的元素)可在其外部加一个span包围，然后用span的id调用此插件即可，这样响应区域就是整个checkbox,radio等所在的区域
 */
jQuery.fn.tcisvFormErrorTip  =   function(options)
{
    if(typeof(options) != 'object')
    {
        /**
         * 转成对象,否则后续判断options['msg']会出错
         */
        options =   {};
    }

    /**
     * 删除所有错误提示相关的对象及事件 
     */
    if(options['action'] == 'removeAll')
    {
        $('[rel="tcisvFormError"]').each(function(i){
            $(this).unbind();

            var et  =   $(this).next('.tcisvFormErrorTag');
            if(et)
            {
                et.unbind().remove();
            }

            var tipId   =   '#' + $(this).attr('id') + 'tcisvFormErrorTip';
            if($(tipId).length)
            {
                $(tipId).remove();
            }
        });

        return true;
    }

    /**
     * 删除当前对象错误显示及相关事件 
     */
    if(options['action'] == 'remove')
    {
        $(this).unbind();
        var errorTag    =   $(this).next('.tcisvFormErrorTag');
        if(errorTag)
        {
            errorTag.unbind().remove();
        }

        var tipId   =  '#' + $(this).attr('id') + 'tcisvFormErrorTip';
        if($(tipId).length)
        {
            $(tipId).remove();
        }

        return true;
    }

    var defaultOptions  =   {
        'class' :   'tcisvFormErrorTip',
        'msg'   :   '没有指定信息！',
        'offSetX'   :   10,
        'offSetY'   :   15,
        'action'    :   'add'
    };

    var $this   =   $(this);
    var tipId   =   $(this).attr('id') + 'tcisvFormErrorTip';

    /**
     * 加rel，便于后期清除事件等 
     */
    $(this).attr('rel', 'tcisvFormError');
    var errorTag    =   $('<span class="tcisvFormErrorTag">?</span>');
    $this.after(errorTag);
   
    var opts    =   $.extend(defaultOptions, options);
    var html    =   '<div class="' + opts['class'] + '" id="' + tipId + '">' + opts['msg'] + '</div>';
    var tip     =   $(html);
    $('body').append(tip);

    /**
     * 绑定事件到当前对象 
     */
    $(this).hover(
        function(){tip.show();run();},
        function(){tip.hide();}
    );

    /**
     * 绑定事件到错误提示符 
     */
    errorTag.hover(
        function(){tip.show();run();},
        function(){tip.hide();}
    );

    var run   =   function()
    {
        var wh  =   window.screen.height;
        var ww  =   window.screen.width;
        var scrTop  =   document.body.scrollTop || document.documentElement.scrollTop;
        var scrLeft =   document.body.scrollLeft || document.documentElement.scrollLeft;
        var offSetY =   opts['offSetY'];
        var offSetX =   opts['offSetX'];

        var tipHeight   =   tip.height();
        var tipWidth    =   tip.width();
        var offset      =   $this.offset();
        var x   =   offset['left'];
        var y   =   offset['top'];
        var tipTop      =   y + offSetY;
        var tipLeft     =   x + offSetX;

        if((x - scrLeft + offSetX + tipWidth) > ww)
        {
            tipLeft =   x - (offSetX * 2) - tipWidth;
        }

        if((y - scrTop + offSetY + tipHeight) > wh)
        {
            tipTop  =   y - (offSetY * 2) - tipHeight;
        }

        tip.css({'top' : tipTop + 'px', 'left' : tipLeft + 'px'});
    }

}

/**
 * formMsg 
 * 显示针对表单的错误信息
 * 
 * @param msg $msg 
 * @access public
 * @return void
 */
function formMsg(msg)
{
    if(typeof(msg) != 'object')
    {
        alert('消息格式有误！');
        return false;
    }

    /**
     * $('body')是随意写的,可以$()任何一个已存在的dom,为的是能够调用tcisvFormErrorTip
     * 先清除已存在的部分对象及其事件
     */
    $('body').tcisvFormErrorTip({action:'removeAll'});

    alert('您输入的信息有误！请把鼠标移至有红色问号的项目上即可看到错误信息！');
    $.each(msg, function(k,v){
        var op = {msg: v.text};
        $('#' + v.id).tcisvFormErrorTip(op);
    });
}

/*
msgResetForm(msg)主要用于增加后的提示信息，msg={status:true,text:'提示信息',id:'tForm'},status表示后台执行是否正确，如果status=true，则重置form id=msg.id的表单,否则只显示提示信息，text是提示信息,msg.id默认为tForm
*/
function msgResetForm(msg)
{
	if(typeof(msg)!='object')
	{
		alert('消息格式有误！');
		return false;
	}
	if(typeof(msg.id)=='undefined')	msg.id = 'tForm';
	if(msg.text)	alert(msg.text);
	if(msg.status)
	{
		document.getElementById(msg.id).reset();
	}
}

/*
msgReload(msg)根据msg中的设置重载当前页面,msg={status:true,text:'提示信息'},如果msg.status=true则重载当前页面，否则只显示提示信息
适用于编辑过的提示信息
*/
function msgReload(msg)
{
	if(typeof(msg)!='object')
	{
		alert('消息格式有误！');	
		return false;
	}
	if(msg.text)	alert(msg.text);
	if(msg.status)
	{
		progress('show','正在载入您刚才编辑的数据，请稍等···');
		window.location.href=window.location.href;//重新载入当前页面
	}
}
/*
msgRedirect(msg)显示信息并跳转到指定地址,msg={status:true,text:'提示信息','url'=>'index.php'},msg.url是需要跳转到的网址
适用于删除后跳到指定的网址
*/
function msgRedirect(msg)
{
	if(typeof(msg)!='object')
	{
		alert('消息格式有误！');	
		return false;
	}
	if(msg.text)	alert(msg.text);
	if(msg.url)
	{
		progress('show','正在进行系统跳转，请稍等···');	
		window.location.href=msg.url;//转到指定url
	}
}


//tcAccordion需要jquery.cookid.js
/*
tcAccordion需要的html结构如下:
<dl id="accordion">
	<dt>主菜单</dt>
	<dd>
		子菜单项(可用ul等,无特别要求)
	</dd>
</dl>
最好在dl外层在放置一个结构,来限制其大小,位置

调用方法:
$(function(){
	$('#accordion').tcAccordion();
})
*/

jQuery.fn.tcAccordion=function(){
	$.each($(this).children('dd'),function(){$(this).css('display','none');});
	$(this).height('100%');/*dd显示时,ie6,7中会把它dt,dd的高度相加作为dl的高度,而不是返回为dl指定的高度，此处为其重新指定高度*/
	var dlH = $(this).height();//dl的高度
	var dtH = 0;//所有dt的高度总和
	var ddH = 0;//dd的高度
	var dtPrefix = 'tcisv-accorditon-dt-';
	$.each($(this).children('dt'),function(k,v){//此步骤主要是计算出所有dt的高度总和
		$(this).attr('id',dtPrefix+k).css('cursor','default');//指定id用于保存选中状态
		dtH += $(this).height();
	});
	ddH = dlH - dtH;
/*还原已选中项*/	
	var selected = $.cookie('t-accordion-selected');
	selected = '#'+(selected || (dtPrefix+'0'));	
	var defaultDd = $(selected).next('dd');
	if(defaultDd)
	{
		defaultDd.css('display','block').css('overflow','auto').height(ddH);
	}
	
	$.each($(this).children('dt'),function(k,v){
		$(this).click(function(){
			$.cookie('t-accordion-selected',$(this).attr('id'),{path:'/'});
			$(this).parent().children('dd').css('display','none');
			var dd = $(this).next('dd');
			dd.css('display','block').css('overflow','auto').height(ddH);			
		});
	});
}

/**
 * tableHover 
 * 为表格加指向变色和隔行变色
 * 需使用此功能的表格要加上rel="tr-color"
 * 
 * @access public
 * @return void
 */
function tableHover()
{
	$('table[rel=trColor] tr:even').addClass('trColor');//表格隔行变色，鼠标在行上面时变色,table加rel='tr-color'
	$('table[rel=trColor] tr').hover(
		function(){$(this).addClass('trColorOver');},
		function(){$(this).removeClass('trColorOver');}
	);
}

/**
 * 此为jquery插件形式，其它和function tableHover一致，
 * 用包含表格的对象调用此插件
 */
jQuery.fn.tableHover = function()
{
    $(this).find('table[rel=trColor] tr:even').addClass('trColor');
    $(this).find('table[rel=trColor] tr').hover(
		function(){$(this).addClass('trColorOver');},
		function(){$(this).removeClass('trColorOver');}
    );
}

$(function(){//执行部分初始化操作,在实际使用过程中，可根据需要，是否加入此部分
	$('#save').click(submitForm);//为工具栏区域的"保存"按钮加上提交表单的动作
	$('form').attr('target','tcisvTo').submit(function(){progress('show');});//为所有的表单提交时加入进度条
	$('form[rel=notarget]').attr('target','_self');//把目标改为_self,针对不需要更改目标的
	//$('a[href]').click(function(){progress('show','正在载入页面，请稍等···');});//为所有的链接加入进度条
	$('a[rel=noprogress]').click(function(){progress('show','正在载入页面，请稍等···');});//为所有的链接加入进度条
	$('a[rel=del]').attr('target','tcisvTo').click(function(){	//为所有的删除链接加确认框,识别删除链接的标志是a中加入rel='del'
		progress('hide');
		if(confirm('您确认是要删除当前数据吗？'))
		{
			return true;
		}
		else
		{
			return false;
		}
	});		
	
    tableHover();	

	$('ul[rel=liColor] li:even').addClass('liColor');//ul列表隔行变色，鼠标在行上面时变色,ul加rel='li-color'
	$('ul[rel=liColor] li').hover(
		function(){$(this).addClass('liColorOver');},
		function(){$(this).removeClass('liColorOver');}
	);

    /**
     * 选择框全选／反选 
     */
    $('input[type=checkbox][name=checkAll]').checkAll();
});//初始化结束


function tpl(data,tplId)//解析js模板,data是json格式数据(一维数组),tplId是模板id,其主要作用就是用data中数据替换tpl中与json数据元素名称相同的字符串
{
	var tplTagStart = '_TC-S-';//开始标记
	var tplTagEnd   = '_TC-E-';//结束标记
	
	if(typeof(data)=='undefined' || typeof(data)!='object')	return false;
    if(!tplId)  
    {
        alert('请指定模板编号！');
        return false;
    }
	var tpl = $('#'+tplId).html();
	if(typeof(tpl)=='undefined')
	{
		alert('没有找到指定的模板！');	
		return false;
	}
	
	if(typeof(tpl)=='undefined')	return false;
	$.each(data,function(k,v){						 
		var r = '\/'+tplTagStart+k+tplTagEnd+'\/g';	
		tpl = tpl.replace(eval(r),v);
	});
	
	return tpl;
}
function tpl2(data,tpl)//解析js模板,data是json格式数据(一维数组),tpl是模板内容，其他同tpl()
{
	var tplTagStart = '_TC-S-';//开始标记
	var tplTagEnd   = '_TC-E-';//结束标记
	
	if(typeof(data)=='undefined' || typeof(tpl)=='undefined')	return false;
	$.each(data,function(k,v){					 
		var r = '\/'+tplTagStart+k+tplTagEnd+'\/g';		
		tpl = tpl.replace(eval(r),v);		
	});
	
	return tpl;
}

function array2PhpJson(d)//把d(二级数组)转换成php能够接受的ＪＳＯＮ格式
{
	var tmp = [];
	$.each(d,function(k,v){
		var tmp2 = [];
		$.each(v,function(k2,v2){
			tmp2[tmp2.length] = '"'+k2+'":"'+v2+'"';
		});
		tmp[tmp.length] = '{'+tmp2.join(',')+'}';
	});
	var json = '['+tmp.join(',')+']';
	
	return json;
}

function _import(path,type)//path需导入文件的路径,type是文件类型,其值为js,css,html
{
	if(!path)
	{
		alert('需导入的文件路径有误!');
		return false;
	}
	type = type ? type : 'js';
	
	switch(type)
	{
		case 'js':
			var h = '<script type="text/javascript" src="'+path+'"></script>';
			document.write(h);
			break;
		case 'css':
			var h = '<link href="'+path+'" rel="stylesheet" type="text/css" />';
			document.write(h);
			break;
		case 'html':
			$.ajaxSetup({global:false,timeout:10000,async:false});	
			$.get(path,function(d){$('body').append(d);});//载入对话框模板
	}
	
	return true;
}

function tClearForm(obj)	//清空表单内容.obj={name:'form',id:'test'},可以指定表单name或表单id.
{
	var o;//表单对象
	if(typeof(obj.name)!='undefined')
	{
		o = $('form[@name='+obj.name+']')[0];
	}
	else if(typeof(obj.name)!='undefined')
	{
		o = $('#'+obj.id)[0];
	}
	else
	{
		return false;
	}
	
	$.each(o,function(k,v){
		if(v.type=='checkbox' || v.type=='radio')
		{
			v.checked = false;
		}
		else if(v.type=='text' || v.type=='password' || v.type=='textarea')
		{
			v.value = '';
		}
		else if(v.type=='select-one')
		{
			v.selectedIndex = 0;
		}
	});
}

function tFormGet(obj)	//以GET方式提交表单,obj = {name:'',id:'',action:''}
{
	var o;//表单对象
	if(typeof(obj.name)!='undefined')
	{
		o = $('form[@name='+obj.name+']')[0];
	}
	else if(typeof(obj.name)!='undefined')
	{
		o = $('#'+obj.id)[0];
	}
	else
	{
		return false;
	}
	
	if(typeof(obj.action)=='undefined')	return false;	

	var r = [];
	$.each(o,function(k,v){
		if(v.type!='button' || v.type=='image')	r[r.length] = v.name+'='+v.value;	//按钮和图片按钮不提交
	});	
	
	var url = obj.action.indexOf('?')==-1 ? obj.action+'?' : obj.action+'&';	//组装成标准的url,为下面做准备
	url = r.length>0 ? url+r.join('&') : url;

	window.location.href=url;	
}


/*
 * jQuery CheckBox CheckAll&Invert
 * version: 0.03 (07/15/2008)
 * @requires jQuery v1.2.2 or later
 * 全选／反选插件
 *  
 *  $(function(){
 *      var chkOption   =   {
 *          invert  :   '#invert',  //执行反选操作的对象编号
 *          all     :   '#all',     //执行全选操作的对象编号
 *          item    :   '.checkitem'    //被选择的对象，此处用class指定的
 *      };
 *  });
 *  $(this).checkInit(chkOption);
 *
 */
 
(function($){
	$.fn.checkInit = function(options) 
    {
        if(options.all != null)     $(options.all).click(function(){$(this).checkAll(options);});
		if(options.invert != null)  $(options.invert).click(function(){$(this).invert(options);});
	};

	$.fn.checkAll = function(options) 
    {
        $(options.item).each(function(i)
        {
            this.checked = true;
        });
	};
	
	$.fn.invert = function(options) 
    {
        $(options.item).each(function(i)
        {
            this.checked = this.checked ? false : true;
        });
	};
})(jQuery);

jQuery.fn.offset = function(options, returnObject) {
var x = 0, y = 0, elem = this[0], parent = this[0], sl = 0, st = 0, options = jQuery.extend({ margin: true, border: true, padding: false, scroll: true }, options || {});
do {
     x += parent.offsetLeft || 0;
     y += parent.offsetTop     || 0;

     // Mozilla and IE do not add the border
     if (jQuery.browser.mozilla || jQuery.browser.msie) {
      // get borders
      var bt = parseInt(jQuery.css(parent, 'borderTopWidth')) || 0;
      var bl = parseInt(jQuery.css(parent, 'borderLeftWidth')) || 0;

      // add borders to offset
      x += bl;
      y += bt;

      // Mozilla removes the border if the parent has overflow property other than visible
      if (jQuery.browser.mozilla && parent != elem && jQuery.css(parent, 'overflow') != 'visible') {
       x += bl;
       y += bt;
      }
     }

     var op = parent.offsetParent;
     if (op && (op.tagName == 'BODY' || op.tagName == 'HTML')) {
      // Safari doesn't add the body margin for elments positioned with static or relative
      if (jQuery.browser.safari && jQuery.css(parent, 'position') != 'absolute') {
       x += parseInt(jQuery.css(op, 'marginLeft')) || 0;
       y += parseInt(jQuery.css(op, 'marginTop'))     || 0;
      }

      // Exit the loop
      break;
     }

     if (options.scroll) {
      // Need to get scroll offsets in-between offsetParents
      do {
       sl += parent.scrollLeft || 0;
       st += parent.scrollTop     || 0;

       parent = parent.parentNode;

       // Mozilla removes the border if the parent has overflow property other than visible
       if (jQuery.browser.mozilla && parent != elem && parent != op && parent.style && jQuery.css(parent, 'overflow') != 'visible') {
        y += parseInt(jQuery.css(parent, 'borderTopWidth')) || 0;
        x += parseInt(jQuery.css(parent, 'borderLeftWidth')) || 0;
       }
      } while (parent != op);
     } else {
      parent = parent.offsetParent;
     }
} while (parent);

if ( !options.margin) {
     x -= parseInt(jQuery.css(elem, 'marginLeft')) || 0;
     y -= parseInt(jQuery.css(elem, 'marginTop'))     || 0;
}

// Safari and Opera do not add the border for the element
if ( options.border && (jQuery.browser.safari || jQuery.browser.opera) ) {
     x += parseInt(jQuery.css(elem, 'borderLeftWidth')) || 0;
     y += parseInt(jQuery.css(elem, 'borderTopWidth'))     || 0;
} else if ( !options.border && !(jQuery.browser.safari || jQuery.browser.opera) ) {
     x -= parseInt(jQuery.css(elem, 'borderLeftWidth')) || 0;
     y -= parseInt(jQuery.css(elem, 'borderTopWidth'))     || 0;
}

if ( options.padding ) {
     x += parseInt(jQuery.css(elem, 'paddingLeft')) || 0;
     y += parseInt(jQuery.css(elem, 'paddingTop'))     || 0;
}

// Opera thinks offset is scroll offset for display: inline elements
if (options.scroll && jQuery.browser.opera && jQuery.css(elem, 'display') == 'inline') {
     sl -= elem.scrollLeft || 0;
     st -= elem.scrollTop     || 0;
}

var returnValue = options.scroll ? { top: y - st, left: x - sl, scrollTop:     st, scrollLeft: sl }
            : { top: y, left: x };

if (returnObject) { jQuery.extend(returnObject, returnValue); return this; }
else                 { return returnValue; }
};


/**
 * checkboxTag 需要选中的checkbox用rel='checkboxTag'进行标记
 * checkboxTag默认值为checkboxAll
 */
jQuery.fn.checkAll  =   function(checkboxTag)
{
    if(typeof(checkboxTag) == 'undefined')
    {
        checkboxTag = 'checkboxAll';
    }

    $(this).click(function(){
        var status  =   $(this).attr('checked');
        status  =   status  ?   true    :   false;
        $('input[rel='+checkboxTag+']').each(function(i){
            $(this).attr('checked', status);
        });
    });
}

/**
 * submitForm2(option)带提醒信息的提交表单方法,一般用地多项删除\审核等 
 * option = {
 *      formId : '表单区域的编号,默认为tForm', 
 *      choiceId : '已选择的数据标识符,必选项，必须符合jQuery的选择符标准',
 *      noChoiceMsg : '没有找到选择项时的提示信息,默认为"请选择需要操作的数据!"',
 *      confirmMsg  : '操作确认信息,默认为"您确认进行此操作吗?"',
 *      action  : '执行操作的表单action,此为必须项,没有此项,无法执行后续操作'
 *      target : 表单打开的目标,默认为tcisvTo;可选值有_self, _blank, tcisvTo
 *  }
 */
jQuery.fn.submitForm2 = function(option)
{
    if(!option['action'])
    {
        alert('没有数据处理动作，数据无法处理！');
        return false;
    }

    option['formId'] = (option && option['formId']) ?   option['fromId']    :   'tForm';
    option['noChoiceMsg'] = (option && option['noChoiceMsg'])   ?   option['noChoiceMsg']   :   '请选择需要操作的数据！';
    option['confirmMsg'] = (option && option['confirmMsg']) ?   option['confirmMsg']    :   '您确认进行此操作吗？';
    option['choiceId']   =  (option && option['choiceId'])  ?   option['choiceId']  :   'input[rel=checkboxAll]';
    option['target']    =   (option && option['target'])    ?   option['target']  :   'tcisvTo' ;

    $(this).click(function(){
        var choiced =   $(option['choiceId']);
        if(choiced)
        {
            var choicedStatus = false;
            $.each(choiced, function(k, i){
                if(this.checked)
                {
                    choicedStatus = true;
                }
            });
        }

        if(!choiced || !choicedStatus)
        {
            alert(option['noChoiceMsg']);
            return false;
        }

        if(!confirm(option['confirmMsg']))
        {
            return false;
        }

        var formObj = $('#' + option['formId']);
        formObj.attr('action', option['action']).attr('target', option['target']).attr('method', 'post');
        formObj[0].submit();
    });
}

