﻿/***********************************************************************************************

************************************************************************************************/

//
//文件范围内所有对象申请
//
var PsItem = Class.create();
var PsReader = Class.create();  //OPS文本只读器
var PsContext = Class.create(); //OPS上下文
var PsObjectBase = Abstract.create();
var PsListTabBase = Abstract.create();
var PsObject = Class.create();
var PsObjectList = Class.create();


PsItem.McheckAttri = "ops:mcheck";  //是否为check 组的属性
PsItem.SecretAttri = "ops:secret";  //是否采用 js escape 加密的属性
PsItem.NoteAttri   = "ops:note";    //自定义Note的属性
PsItem.TypeAttri   = "ops:type";    //[at,tc,ps]
PsItem.BindAttri   = "ops:bind";	   //[n:Note;t:Text;m:Name;p:Type;]在绑定数据时,使用Text还是Note;//默认为Text
PsItem.BUILD_ENTITY= false;       //是否要构建实体()
PsItem.STORAGE_OPTIMIZE = true;     //存储最优化(是否开启)
PsItem.AUTO_NOTE_SELECT = true;    //是否自动记录select 对象的text作为Note数据(另外还可以加ops:note属性添中资料)

//2007-03-27,谢月甲,新增加的属性
//新加了 ondataitembond 事件

//-----------------------------------------------------------------------------------------------
var OPS = {
    Version		: "3.07.0318_r3",
    LastUpdate  : "2007.08.12",
    Anthor	    : "谢月甲||没有耳多||CWZB||CWZB工作室||http://www.cwzb.name",
    Keyword     : "面向页面存储||面向页面整体存储||OPS||OPS 框架",
    Note		: "OPS 仅对表单的数据绑定有效",
    Using       : "../../Surprise.JS.Extend.js",
    UsingNote   : "为了推广“$()”及“_()”方法;$()返回某元素,_()返回某窗体框架"
}

OPS.toString = function(){
    return "[Object OPS]";
}

OPS.Type = {
    AT : "at",
    TC : "tc",
    PS : "ps"
}
OPS.New = function(entityName,t)
{
	switch(t)
	{
		case "ps":
			return new PsContainer(entityName);
		
		case "at":
			return new ActiveTable(entityName);
		
		case "tc":
			return new TempletCard(entityName);
							
		default:
			return new PsContainer(entityName);
	}	
}
//
//(key,[val]) if(val == null) cache is getter;else cache is setter
//
OPS.cache = function(key,val)
{
    if(window.ops_cache == null)
        window.ops_cache = new HashTable();
    
    if(key == null)
        return null;
    
    if(val == null)
        return window.ops_cache.$V(key);
    else
    {
        if(window.ops_cache.add(key,val) == false)
            window.ops_cache.item(key).value = val;
    }
}


//概据"上下文"和标签,在容器里获取表单控件
//
//@c        :Ops上下文

//@tagName  :标记名称
//@typeName :类型名称(可选,或者可以是一个数组)
//
OPS.$FT = function(c,tagName,undoAttri,typeName)//c:PsContext
{
    var temp = c.con.getElementsByTagName(tagName);
    var list = new Array();
    var item = null;
    
    //------------------>>
    //  对不操作属性的支持
    var tempUndo;
    if(undoAttri == null)
        tempUndo = "__";
    else
        tempUndo = undoAttri;
    //------------------>>
    
    if(typeName == null)
    {
        $Foreach(temp,function(e){
        		    
		    if(e[tempUndo] != 1)
			    list.push(e);
        });
        
        return list;
        
    }
    else
    {
	    var len   = temp.length;
	        
        if(typeof(typeName) == "string")
        {   
	        for(var i=0; i<len; i++)
	        {
	            item = temp[i];
		        if(item.type == typeName && item[tempUndo] != 1)
			        list.push(item);
	        }
	    }
	    else
	    {
	        for(var i=0; i<len; i++)
	        {
	            var added = false;
	            $Foreach(typeName,function(e){	        
    		        item = temp[i];
		            if(added == false && item.type == e && item[tempUndo] != 1)
			            list.push(item);
			    });
	        }
	    }
	    
	    return list;
	}
}

//根据上下文和关键字,在容器里取出表单控件
//
//@c    :Ops上下文
//@name :控件ID或Name
//[@tag]	:控件标签
OPS.FSTR = "input,textarea,select";
OPS.$FM = function(c,key)
{
    if(typeof(key) == "string")
    {		
        var tempAry = c.con.all[key];//getElementsByName(name);
        
        if(tempAry.nodeName != undefined) //说明已经是一个节点了
			return tempAry;
		else
        {
			var ary  = new Array();
			$Foreach(tempAry,function(e)
			{
				if(OPS.FSTR.indexOf(e.nodeName.toLowerCase()) > -1)
					ary.push(e);
			});
			
			if(ary.length == 1)
				return ary[0];
			else
				return ary;
		}		
		
    }
    else
        return name;
}
//根据key对一个表单组进行筛选
//
//@list 为一个对象或多个对象
//@key  不id或name
OPS.Select = function(list,key)
{
	var ary = new Array();
	$Foreach(list,function(e)
	{
		if(e.id == key || e.name == key)
			ary.push(e);
	});
	
	if(ary.length == 1)
		return ary[0];
	else
		return ary;
}
//-------------------------------------------------------------------
//
//OPS 数据拷贝
//
//@pso ：用来提供OPS数据的OPS 对象（或者直接OPS数据）
//
OPS.copy = function(pso)		//将一个OPS对象的数据拷贝到内存里
{
    var xml = null;
    if(typeof(pso) == "string")
        xml = pso;
    else
        xml = pso.toXml();
        
	clipboardData.setData("text",xml);
}

//
//OPS 数据粘贴
//
//@pso ：用来接受OPS数据的OPS 对象
//
OPS.paste = function(pso)	//将一份内存里的数据拷贝到OPS对象里
{
    var xml = clipboardData.getData("text");
    
    if(xml != null)
	{
		try
		{
			pso.load(xml);
		}
		catch(e){}
	}
}

//--------------------------------------------------------<<

//
//Ps文本读取器,类似于xml reader
//
PsReader.extend({
    initialize : function()
    {
        this.psText       = "" ;
        
        this.index = 0 ;
        this.name  = "";
        this.data  = "";  
    },
        
    loadOpsText : function(p_ops,tagName,unStrict)//父一级ops内容
    {
		this.index = 0;			//重置索引
		
		if(p_ops == null) return;
		
		var tagName1 = tagName;
		
		unStrict = true;
		
		if(unStrict == true)
		    tagName1 = PsReader.getName(p_ops);
		
		var tagStart = "<" +tagName1+">";
        var tagEnd   = "</"+tagName1+">";
                
        var startPoint = p_ops.indexOf(tagStart); 
        var endPoint  = p_ops.lastIndexOf(tagEnd );
        
        this.psText = p_ops.substring(startPoint + tagStart.length, endPoint);
    },    
     
    read : function()   //读取下一个节点

    {
        var potStart = this.psText.indexOf("<",this.index);
        var potEnd   = this.psText.indexOf(">",this.index);
              
        if(potStart < 0)
            return false;
        else
        {
            this.name = this.psText.substring(potStart + 1,potEnd);
                        
            this.data = this.getData();
            
            this.index = this.index + this.name.length + 3;
            
            return true;
        }
    },
    
    getData : function(index)
    {
        var tagStart = "<"+this.name+">";
        var tagEnd   = "</"+this.name+">";
        var tagAll   = "<"+this.name+" />";
                    
        var potStart = this.psText.indexOf(tagStart, this.index);               
        var potEnd   = this.getPotEnd(tagStart,tagEnd, potStart);    
        
	    if(potStart < 0)
		    return "";
	    else
	    {
	        this.index = potEnd;
	        
		    return this.psText.substring(potStart + tagStart.length, potEnd);
		}
    },
    
    getPotEnd : function(tagStart,tagEnd, potStart)
    {
        if(potStart < 0)
            return -1;
        else
        {
             var endIndex = this.psText.indexOf(tagEnd,potStart + 2);//第二次取
             var startIndex = this.psText.indexOf(tagStart,potStart + 2);//第一次取
                                       
             if(startIndex > 0)
             {
                 while(startIndex < endIndex)
                 {                  
					endIndex = this.psText.indexOf(tagEnd,endIndex + 2);//n+1
					
                    startIndex = this.psText.indexOf(tagStart,startIndex + 2);//n+2
                    
                    if(startIndex < 0)
						return endIndex;					
                 }
             }
             
             return endIndex;
        }
    }
});

//
//从某一项OPS数据里,快速取出一段标记间的值
//
//@ops      :OPS字符串
//@tagName  :标签名
//@index    :开始搜索的索引位置(不输入时,默认为0)
PsReader.getValue = function(ops,tagName,index)
{
    var tagStart = "<"+tagName+">";
    var tagEnd   = "</"+tagName+">";
    var tagAll   = "<"+tagName+" />";
    
    if(index == null)
        index = 0;
        
    var potStart = ops.indexOf(tagStart, index);
    var potEnd   = ops.lastIndexOf(tagEnd);//使用lastIndexOf可以在<Text>...</Text>较长时有效提高速度
        
    if(potStart < 0)
		return "";
	else
	{
		index = potEnd;//将最后的指针回传
		return ops.substring(potStart + tagStart.length, potEnd);
	}	
}

PsReader.getName = function(ops)
{
    var potStart = ops.indexOf("<");
    
    if(ops.substr(potStart+1,1) == "?")
        potStart = ops.indexOf("<", potStart + 1);
    
    var potEnd   = ops.indexOf(">", potStart);
    
    if(potStart < 0)
        return "";
    else
        return ops.substring(potStart + 1,potEnd);
}

//
//  OPS数据寄存器,主要用于单选框的数据操作上
//
var PsState = Class.create();
PsState.extend({
    initialize : function()
    {
        this._State = ",";
    },
    
    add : function(note)
    {
        this._State += note + ",";
    },
    
    has : function(note)
    {
        if(this._State.indexOf("," + note + ",") <0)
            return false;
        else
            return true;
    },
    
    clear : function()
    {
        this._State = ",";
    }
});

//--------------------------------------------------------<<
//
//  OPS项,即页面表单控件的映射,相当于2.0版本的 PSItemParser，但功能更强大，性能更好
//
//
PsItem.U_LOCK = "ops:islocked"; //被锁定的控制项，不可控制其禁用状态
PsItem.extend({
    initialize : function(name,type,text,node)
    {        
        this.Name = name;
        this.Type = type;
        this.Text = text;
        this.Note = (node == null?"":node);
    },
    
    isOpsType : function()
    {
        return (this.Type == "opsxml");
    },
	
	opsSerialize : function()
	{
		if(this.Name == null || this.Name.length == 0)
			return "";
			
		var typeXml = ("<Type>"+this.Type+"</Type>");
		
		//如果要生成实体类则全部返回"Name"与"Type"
		//		
		if(PsItem.BUILD_ENTITY == true )
			return "<"+this.Name+">" + ("<Type>"+this.Type+"</Type>") + "</"+this.Name+">";
			
		if(this.Text.length == 0)
	        return "";
	    else 
	    {	 				
	        //开启最优化存储并且没有Note信息要记录，将输出最少OpsXml，从而实现存储压力
	        //
	        var xmlText;
	        
	        //如果,是AT、PS或TC类型的载体，则实现XML格式保留（在dataBind里将兼容老数据格式）
	        //
	        if(this.isOpsType())
	            xmlText = this.Text;
	        else
	            xmlText = xmlEscape(this.Text);
				
	        var noteXml = (this.Note.length < 1 ? "":"<Note>"+xmlEscape(this.Note)+"</Note>");
	        var textXml = ("<Text>"+xmlText+"</Text>"); 
			
			//开启了最优化处理,并且不是OPSTYPE类型的
			//			
	        if(PsItem.STORAGE_OPTIMIZE && (this.isOpsType() == false))
	        {
	            if(this.Note.length < 1)
	                return "<"+this.Name+">" + xmlText + "</"+this.Name+">";
	            else
	                return "<"+this.Name+">" + textXml + noteXml + "</"+this.Name+">";
	        }
			else	       
				return "<"+this.Name+">" + typeXml + textXml + noteXml + "</"+this.Name+">";
	    }
	},
	
	disabled : function(psContext,val,style)
    {
        try
        {
            var temp = OPS.$FM(psContext,this.Name);
    		
		    switch(this.Type)
		    {
		        case "mcheck":
		        case "radio":
		        case "check1":	
				    $Foreach(temp,function(e){
				        if(e.getAttribute(PsItem.U_LOCK) != "true")
				        {
					        e.disabled = val;
					        e.style.cssText = style;
					    }
				    });
			    break;
    			
			    default:
			        if(temp.getAttribute(PsItem.U_LOCK) != "true")
			        {
			            temp.disabled = val;		            
			            temp.style.cssText = style;
			        }
			    break;
    			
		    }
        }
        catch(e){}
    },
	$ : function(key)
	{
		switch(key)
		{
		    case "n":
			    return this.Note;
			case "t":
				return this.Text;
			case "m":
				return this.Name;
			case "p":
				return this.Type;
		}
	}
});

//
//获取一个对象的关键字,id优先
//
PsItem.$K = function(obj)
{
    if(obj.id != null && obj.id.length > 0)
	    return obj.id;
	else
	    return obj.name;
}

//
//获取一个对象的Note
//
PsItem.$N = function(obj)
{
    var note = obj.getAttribute(PsItem.NoteAttri);
    
    if(note == null)
        return "";
    else
        return note;
}

//
//获取一个对象的PsItemType(主要，供dataBind时，使用(是否为AT，TC，PS，无关要紧))
//
PsItem.$T = function(obj)
{
    var temp;
    if((obj.length != null) && (obj[0].nodeName.toLowerCase() != "option"))
        temp = obj[0];
    else
        temp = obj;
    
    //如果标有ops:type 则直接返回类型;
    var attrType = temp.getAttribute(PsItem.TypeAttri);
    
    if(attrType != null)
        return attrType;    
    
    
    var nodeName = temp.nodeName.toLowerCase();
      
    switch(nodeName)
    {
        case "input":
        {
            var type = temp.type;
            
            switch(type)
            {
                case "hidden":
                case "password":
                case "text":
                {
                    if(temp.getAttribute(PsItem.SecretAttri) != "1")
                        return "value";
                    else
                        return "storage";
                }
                
                case "checkbox":
                {
                    if(temp.getAttribute(PsItem.McheckAttri) != "1")
                        return "check1";
                    else
                        return "mcheck";
                 }
                 
                 case "radio":
                    return "radio";
            }
        }break;
        
        case "select":
        {
            if(temp.multiple == false)
                return "select1";
            else
                return "mselect";
        }break;
        
        case "textarea":
            return "value";
            
        default://如果不是，则属于非表单元素。(需要使用innerText 进行赋值)
            "text";
    }
}

//
//根据OpsText 创建PsItem,专用于load时使用
//
PsItem.buildByT = function(name,psText)
{
    var temp = new PsItem();
    var index = 0;
    
    temp.Name = name;
    temp.Type = PsReader.getValue(psText,"Type",index);
    temp.Text = PsReader.getValue(psText,"Text",index);   
    temp.Note = PsReader.getValue(psText,"Note",index);
    
    //var indexOfTxt = psText.indexOf("<Text>");
        
    //当type == '' && text == '' && note == '' 时,说明采用了最优化存储:<CN_Name>.......</CN_Name；dataBind() 时，需要对Type进行运算类型
    //
    if((temp.Type.length == 0 ) && (temp.Text.length == 0) && (temp.Note.length == 0))
    {       
        temp.Text = xmlUnescape(psText);
    }
    else
    {   
        //不需要对js escape 加密的数据进行 unescape，在dataBind方法里会进行操作
        //
        if(temp.isOpsType())
            temp.Text = temp.Text;
        else
            temp.Text = xmlUnescape(temp.Text);
                        
        temp.Note = xmlUnescape(temp.Note);
    }
    
    return temp;
}

//
//根据页面控件 创建PsItem,专用于toXml时使用
//
PsItem.buildByC = {     
    value : function(e)
    {
        var temp = e.getAttribute(PsItem.TypeAttri);
        
        if(temp) //支持ops:type[at,ps,tc] 属生
            return new PsItem(PsItem.$K(e),temp,e.value,PsItem.$N(e));
        else
            return new PsItem(PsItem.$K(e),"value",e.value,PsItem.$N(e));
    },
    
    check1 : function(e)
    {
        return new PsItem(PsItem.$K(e),"check1",(e.checked?"1":"0"),PsItem.$N(e));
    },
    
    mcheck : function(e)
    {
        var text = "";
        var name = "";
        $Foreach(e,function(e1){
            if(e1.checked)
                text += e1.value + ",";
        });
        
        if(text.length > 0)
            text = "," + text;
        
        if(e.length == undefined)
			name = e.name;
		else
			name = e[0].name;
        
        return new PsItem(name,"mcheck",text);
    },
    
    radio : function(e)//e:已被选中的数据
    {
        var text = "";
		var name = "";
        $Foreach(e,function(e1){
            if(e1.checked)
                text = e1.value;
        });
        
		if(e.length == undefined)
			name = e.name;
		else
			name = e[0].name;
		
        return new PsItem(name,"radio",text);
    },
    
    select1 : function(e)
    {
        var note = PsItem.$N(e);
        
        if(PsItem.AUTO_NOTE_SELECT)//是否自动记录Text
        {
            if(note.length > 0)
                note += ":";
            
            if(e.selectedIndex > -1)
                note += e.options[e.selectedIndex].text;
        }
        
        return new PsItem(PsItem.$K(e), "select1", e.value, note);
    },
    
    mselect : function(e)
    {
        var note = PsItem.$N(e);
        var text = "";
        
        if(PsItem.AUTO_NOTE_SELECT)//是否自动记录Text
        {
            if(note.length > 0)
                note += ":";
        }
        
        $Foreach(e.options,function(e1){
			if(e1.selected)
			{
				text += e1.value + ",";
				
				if(PsItem.AUTO_NOTE_SELECT)//是否自动记录Text
				    note +=e1.text + ",";
		    }
		});
		
		if(text.length > 0)
            text = "," + text;
			
        return new PsItem(PsItem.$K(e),"mselect",text,note);
    },
    //
    //不建议采用该方面创建escape数据，因为不利用OPS全文搜索
    //
    storage : function(e)//用来放置需要js escape的数据
    {
        return new PsItem(PsItem.$K(e),"storage",escape(e.value),PsItem.$N(e));
    }
}

//
//为OPS 控制页面，做上不可禁用的标记，专为配全PsItem.p.disabled 进行使用
//
//@type :是指OPS控制项类型
//@e    :是指OPS控制项
//@style:目前，只能用为北景色来处理
PsItem.markTag = function(type,e,style)
{
    try
    {		
		switch(type)
		{
		    case "mcheck":
		    case "radio":
		    case "check1":
				$Foreach(e,function(e1){
					if(e1.disabled)
					{
					    e1.setAttribute(PsItem.U_LOCK,"true");
					    e1.style.cssText = style;
					}
				});
			break;
			
			default:
			    if(e.disabled)
			    {
			        e.setAttribute(PsItem.U_LOCK,"true");
			        e.style.cssText = style;
			    }
			break;
			
		}
    }
    catch(e){}
}
//
//于buildByT之后,将数据绑定给页面
//
PsItem.execReplaceFun = function(replaceFun,e,psItem) 
{
	if(replaceFun == null)
		return true;
	else
	{
		return replaceFun(e,psItem);
	}
} 

PsItem.dataBind = function(psItem,psContext,replaceFun)//replaceFun(e, psitem) :bool {if true then continue exec else return }
{
	try
	{
		var temp = OPS.$FM(psContext,psItem.Name);
		var bind = "t";
		if(temp.getAttribute != null)
		{
			bind = temp.getAttribute(PsItem.BindAttri);
			
			if(bind == null)
				bind = "t";
		}
			
		var text = "";
			
		//
        //当type == ''时,说明采用了最优化存储:<CN_Name>.......</CN_Name；需要进行运算类型
        //
		if(psItem.Type.length < 1)
		{
		   psItem.Type = PsItem.$T(temp);
		}
		
		switch(psItem.Type)
		{
			case "opsxml":
			case "value":
			{
				if(PsItem.execReplaceFun(replaceFun,temp,psItem) == true)
				{
				    var nodeName = temp.nodeName.toLowerCase();
				    
				    if(nodeName == "input" || nodeName == "textarea")
					    temp.value = psItem.$(bind);
					else
					    temp.innerText = psItem.$(bind);
				}
			}
			break;
			
			case "check1":
				$Foreach(temp,function(e){
					if(PsItem.execReplaceFun(replaceFun,e,psItem) == true)
					{
						e.checked = (psItem.Text=="1"?true:false);
					}
				});
			break;
			
			case "mcheck":	
				text = "," + psItem.Text + ",";
				
				$Foreach(temp,function(e){
					if(PsItem.execReplaceFun(replaceFun,e,psItem) == true)
					{
						if(text.indexOf("," + e.value + ",") >= 0)
							e.checked = true;
						else
							e.checked = false;
					}
				});
			break;
			
			case "radio":
				$Foreach(temp,function(e){
					if(PsItem.execReplaceFun(replaceFun,e,psItem) == true)
					{
						if(psItem.Text == e.value)
							e.checked = true;
						else
							e.checked = false;
					}
				});
			break;
			
			case "select1":
				if(PsItem.execReplaceFun(replaceFun,temp,psItem) == true)
					temp.value = psItem.Text;
			break;
			
			case "mselect":
				text = "," + psItem.Text + ',';
				
				$Foreach(temp.options,function(e){
					if(PsItem.execReplaceFun(replaceFun,e,psItem) == true)
					{
						 if(text.indexOf("," + e.value + ",") >= 0)
							e.selected = true;
						else
							e.selected = false;
					}
				});       
			break;
					
			case "storage":
				if(PsItem.execReplaceFun(replaceFun,temp,psItem) == true)
					temp.value = unescape(psItem.$(bind));
			break;			
			
			default://说明没有对应的表单控件，可能采用<div><span>普通的元素进行数据接受了
			    if(PsItem.execReplaceFun(replaceFun,temp,psItem) == true)
					temp.innerText = psItem.$(bind);	
			break;
		}
	}
	catch(e){}
}

//--------------------------------------------------------<<

//
//  Ops 上下文
//
//#con:容器
//#doc:文档
//#win:窗口

PsContext.extend({
    initialize : function(e)			//e:可以是字符串,也可以是对象,如果是对象,则可以跨窗口作业
    {
        this.createBy(e);
    },
    
    createBy : function(e)
    {
        if(e != null)
            this.con = $(e);
        else
            this.con = null;
        
        if(this.con == null)
            this.con = document.documentElement;
        
        this.doc = this.con.ownerDocument;
        this.win = this.doc.parentWindow;
    },
    
    $ : function(e)
    {
        return this.doc.all[e];
    }
});

/*
 * PsObject,PsObjectList
 *
 *  PsObjectBase 对象,(任何OPS UI控件类的基类)
**/

PsObjectBase.extend({
    entityName		: "PsObject",
    undoAttribute	: null,
    context			: null,
    reader			: null,
    opsHid          : null, //存储OPS的控件
    type            : null, //tc or at or ps
	tags			: "",
    _EventTable     : null, //
    defaultStyle    : "",   // 
    disableStyle    : "background-color:#DDDDDD;",   //被禁用项的样式;
    lastBuildXml    : "",
    attachEvent : function(eventName,fun)
    {
         if(this._EventTable == null)
            this._EventTable = new HashTable();
         
         var temp = this._EventTable.$V(eventName);
         
         if(temp == null)
         {
            temp = new Array();
            
            this._EventTable.add(eventName,temp);
         }
         
         temp.push(fun);
    },

    applyEvent : function(eventName,args)
    {
         if(this._EventTable == null)
            return true;
        
         var temp = this._EventTable.$V(eventName);
         
         if(temp != null)
         {
			var result = true;
            var len = temp.length;
            
            for(var i=0; i<len; i++)
                result = (temp[i](args) != false)// true == [null, true]
			
			return result;
         }
		 else
			return true;
    },
     
    detachEvent : function(eventName,fun)
    {
         if(this._EventTable == null)
            this._EventTable = new HashTable();
        
         var temp = this._EventTable.$V(eventName);
         
         if(temp != null)
         {
           var index = temp.indexOf(fun);
           
           temp.removeAt(index);
         }
    },
    
    $ : function(e)
    {            
        if(typeof(e) == "string")
            return this.context.$(e);
        else
            return e;
    }
});


PsListTabBase.extend({
    _CurrentTab: null,
    tabcss     : {defaultStyle : "",currentStyle : "",defaultClass : "",currentClass : ""},  
    selectTab : function(tab)
    {
        if(tab == null)
            return;
            
        this.unselectTab(); 
               
        if(this.tabcss.currentClass != "")
            tab.className = this.tabcss.currentClass;
        else
            tab.style.cssText = this.tabcss.currentStyle;
                
        this._CurrentTab = tab;
    },
    
    unselectTab : function()    //取消当前项的选中
    {
         if(this._CurrentTab != null)
         {
            if(this.tabcss.defaultClass != "")
                this._CurrentTab.className = this.tabcss.defaultClass;
            else
                this._CurrentTab.style.cssText = this.tabcss.defaultStyle;
         }
    },
    
    setLabel : function(t)
    {
        if(this._CurrentTab != null)
            this._CurrentTab.value = t;
    }
    
});



PsObject.extend (PsObjectBase.prototype);
PsObject.extend ({
    initialize : function()
    {   
		this.reader  = new PsReader();
        this.items	= new HashTable();
		this.pType  = null;//父节点类型
        
        this.items.opsSerialize = function()
		{
			var len 	= this.length;
			var opsText = "";
			for(var i=0; i<len; i++)
				opsText += this.$V(i).opsSerialize();
			
			return opsText;
		}
    },
    
    $V : function(key)
    {
        return this.items.$V(key);
    },
    
    count : function()
    {
        return this.items.length;
    },
    
    copy : function()
    {
		var temp = new PsObject();
		
		temp.entityName	   = this.entityName;
		temp.context	   = this.context;
		temp.undoAttribute = this.undoAttribute;
		
		return temp;
    },
    
    load : function(ops,unStrict)
    {   
        //--------------------------------------
        this.lastBuildXml = ops;
        
        if(ops == null)
        {
            if(this.opsHid != null)
            {
                ops = this.opsHid.value;
            }
            else
                return false;
        }    
        
        if(ops.length < 8)
            return false;
            
        //--------------------------------------
                        
		this.loadOnly(ops,unStrict); 
		this.dataBind();
		
		this.applyEvent("onload");
    }, 
    
    //
    //设置所有相关表单控件的disabled值
    //
    disabled : function(val)
    {
        var len   = this.items.length;        
        var style = val?this.disableStyle:this.defaultStyle;
			
		for(var i=0; i<len; i++)
			this.items.$V(i).disabled(this.context,val,style);	
		
		//将控制范围内的Button禁用掉
		//
		var btnS = OPS.$FT(this.context,"input",this.undoAttribute,"button");
		$Foreach(btnS,function(e){e.disabled = val;});
		
		this.applyEvent("ondisabledchange",val);
    },
    
    //
    // 为了使用load 更具有弹性,特分为两部份:1.load ops 并生成实体(this.loadOnly);2.把实体上的数据绑定到页面上(this.dataBind)
    //
    loadOnly : function(ops,unStrict) 
    {
		 this.reader.loadOpsText(ops,this.entityName,unStrict);
         this.readItems();
    },
	
	toOps : function()	//为兼容 m1 版本
	{
		return this.toXml();
	},
	
	//
	//构建实体数据,并序列化成XML
	//
    toXml : function()
    { 
        this.hasChanged();//用于意判断opsXml是否发生过化,但也同时会产生最新的opsXml
        
        return this.lastBuildXml;
	},
	
	hasChanged : function()
	{
	    var temp = this._DoToXml();
	    
	    if(temp == this.lastBuildXml)
	        return false;
	    else
	    {
	        this.lastBuildXml = temp;
	        
	        return true;
	    }
	},
	
    _DoToXml:function()
    {
        this.applyEvent("ontoxmlBefore");
        
        this.buildItems();
		
        return this.opsSerialize();
    },
    
    //
    //为了,支持OPS组件的整合,特别在3.0 r1 版本里,引入该接口.
    //
    //this.save 需要在this.bind 时,绑定this.opsHid(即ops数据的载体控件)
    //
    save : function()
    {
        this.opsHid.value = this.toXml();
    },
    
    opsSerialize : function()
    {
       return  "<"+this.entityName+">"+this.items.opsSerialize()+"</"+this.entityName+">";
    },
    
    dataBind : function()
    {
		var len 	= this.items.length;		
		var my		= this;
			
		for(var i=0; i<len; i++)
			PsItem.dataBind(this.items.$V(i),this.context,function(e,psItem)
				{return my.applyEvent("ondataitembond",[e,psItem]);});
    },
        
    readItems  : function()
    {
		this.items.clear();
		
        while(this.reader.read())
            this.items.add(this.reader.name,PsItem.buildByT(this.reader.name,this.reader.data));
    }, 
       
    //
    //构建OPS 实体项,即实现表单控件到OPS项的映射
    // 
    //@markTag  :在实现印射的过程当中,是否为已禁用的的项作一下标记,方便为其它的项进行禁用控制
    //
    buildItems : function(markTag)
    {
        var my  = this;
        var state = new PsState();
        
        my.items.clear();
        
        //构建value,storage
        var texts = OPS.$FT(this.context,"input",this.undoAttribute,["text","password","hidden"]);
        
        $Foreach(texts,function(e){
            if(e.getAttribute(PsItem.SecretAttri) != "1")
                my.items.add(PsItem.$K(e), PsItem.buildByC["value"](e));
            else
                my.items.add(PsItem.$K(e), PsItem.buildByC["storage"](e));
            
            //
            //用于标记,是否已禁用
            //
            if(markTag == true)
                PsItem.markTag("value",e,my.disableStyle);
        });
        
        //构建textarea
        texts = OPS.$FT(this.context,"textarea",this.undoAttribute);
        
        $Foreach(texts,function(e){
            if(e.getAttribute(PsItem.SecretAttri) != "1")
                my.items.add(PsItem.$K(e), PsItem.buildByC["value"](e));
            else
                my.items.add(PsItem.$K(e), PsItem.buildByC["storage"](e));
            
            //
            //用于标记,是否已禁用
            //
            if(markTag == true)
                PsItem.markTag("value",e,my.disableStyle);
        });
        
        //构建check1,mcheck
        var checks = OPS.$FT(this.context,"input",this.undoAttribute,"checkbox");
        $Foreach(checks,function(e){
            if(e.getAttribute(PsItem.McheckAttri) != "1")
            {
                my.items.add(PsItem.$K(e), PsItem.buildByC["check1"](e));
                
                //
                //用于标记,是否已禁用
                //
                if(markTag == true)
                    PsItem.markTag("check1",e,my.disableStyle);
            }
            else
            {
                if(state.has(e.name))
                    return;
                else
                {
                    var temp = OPS.Select(checks,e.name);
                    my.items.add(e.name, PsItem.buildByC["mcheck"](temp));
                    
                    state.add(e.name);
                    
                    //
                    //用于标记,是否已禁用
                    //
                    if(markTag == true)
                        PsItem.markTag("mcheck",temp,my.disableStyle);
                }
            }
        });
        
        //构建radio
        var radios = OPS.$FT(this.context,"input",this.undoAttribute,"radio");
        $Foreach(radios,function(e){
            if(state.has(e.name))
                return;
            else
            {
                var temp = OPS.Select(radios,e.name);
                my.items.add(e.name, PsItem.buildByC["radio"](temp));
                
                state.add(e.name);
                
                //
                //用于标记,是否已禁用
                //
                if(markTag == true)
                    PsItem.markTag("radio",temp,my.disableStyle);
            }
        });
        
        //构建select1,mselect
        var selects = OPS.$FT(this.context,"select",this.undoAttribute);        
        $Foreach(selects,function(e){
            if(e.multiple == false)
                my.items.add(PsItem.$K(e), PsItem.buildByC["select1"](e));
            else
                my.items.add(PsItem.$K(e), PsItem.buildByC["mselect"](e));
                
            //
            //用于标记,是否已禁用
            //
            if(markTag == true)
                PsItem.markTag("select1",e,my.disableStyle);
        });        
     }
});

//
//  Ops 列表型组件的基类
//

PsObjectList.extend (PsObjectBase.prototype);
PsObjectList.extend ({   
    initialize : function()
    {
		this.reader			= new PsReader();
        this.activePso		= null;						//activePso:PsObject;
        this.list			= new HashTable();
        
        this.list.opsSerialize = function(isAtList)
		{
			var len 	= this.length;
			var opsText = "";
			var item;
			
			for(var i=0; i<len; i++)
			{
			    item = this.$V(i);
			    
			    if(isAtList == true)
		            item.buildItems();
		        
				opsText += item.opsSerialize();
			}
			
			return opsText;
		}
    },
    
    $V : function(key)
    {
        return this.list.$V(key);
    },
    
    count : function()
    {
        return this.list.length;
    },
    
    load : function(ops, unStrict)
    {
        //--------------------------------------
                
        if(ops == null)
        {
            if(this.opsHid != null)
                ops = this.opsHid.value;
        }  
        
        //------------------------------------  
        
        
        if(ops == null || ops.length < 8)
        {
            this.lastBuildXml = "";
            
            this.clear.apply(this);//try{}catch(ex){}//this.clear()由继承类实现            
        }
        else
        {            
            this.reader.loadOpsText(ops,"ArrayOf" + this.entityName, unStrict);
            
            if(this.reader.psText.length > 6)//截出来的数据长度小于6,说明没有值，如：<ArrayOfXXX></ArrayOfXXX>，节点内没有数据
            {
                this._ReadList.apply(this);
                
                if(this.activePso != null)
                    this.activePso.dataBind();
            }
            else
            {
                this.clear.apply(this);
            }
        }
        
        this.lastBuildXml = ops;        
        this.applyEvent("onload");
    },
    
    
	toOps : function()	//为兼容 m1 版本
	{
		return this.toXml();
	},
	
    toXml : function()
	{
	    this.hasChanged();//用于意判断opsXml是否发生过化,但也同时会产生最新的opsXml
        
        return this.lastBuildXml;
	},
	hasChanged : function()
	{
	    var temp = this._DoToXml();
	    
	    if(temp == this.lastBuildXml)
	        return false;
	    else
	    {
	        this.lastBuildXml = temp;
	        
	        return true;
	    }
	},
	
	exists:function(item,value)//统计@item项，值为@value的项有多少
	{
	    this._DoToXml();
	    var temp = 0;
	    var len = this.list.length;
	    for(var i=0; i<len; i++)
	    {	        
	        if(this.$V(i).$V(item).Text == value)
	            temp++; 
	    } 
	    
	    return temp;
	},
	
	_DoToXml:function()
	{
		if(this.count() == 0)
			return "";
			
	    this.applyEvent("ontoxmlBefore");
	    
		var len 	= this.length;
		var opsText = "<ArrayOf"+this.entityName+">";
		
		var isAtList = (this.type == OPS.Type.AT ? true:false);   //at or tc
		
		if(this.activePso != null)
	        this.activePso.buildItems();
		
		opsText += this.list.opsSerialize(isAtList);
		
		return  opsText + "</ArrayOf"+this.entityName+">";
	},
	
	//
	//需要在 bind()时,绑定可存放OPS数据的控件
	//
	save : function()
    {
        if(this.opsHid != null)
            this.opsHid.value = this.toXml();
    }
});
//-------------------------------------
