//valueObject 值对象
assert(web.layout);
import fsys.time;
namespace web.layout;
 
class valueObject{
	ctor (v,...) {
		this = __valueObject_struct(); 
		this@ = _metaProperty;
		
		if( v!==null ){
			this.setValue(v,...);
		}
		..table.gc(this,"clear");
	};
}

var dll = _dll;
var valueObject_t = valueObject ;  

namespace valueObject {
 	class __valueObject_struct{
		INT type;
		INT units;
		LONG data;
	} 
	
	//ValueInit = dll.api("ValueInit", "INT(struct &pval)");
	ValueClear = dll.api("ValueClear", "INT(struct &pval)");
	ValueCompare = dll.api("ValueCompare", "bool(struct pval,struct pval2)");
	ValueCopy = dll.api("ValueCopy", "INT(struct& pdst,struct psrc)"); 

	ValueType = dll.api("ValueType", "INT(struct pval, INT& pType, INT& pUnits)");
	ValueStringDataSet = dll.api("ValueStringDataSet", "INT(struct &pval, pointer chars, INT numChars, INT units)");
	ValueStringData = dll.api("ValueStringData", "INT(struct pval, pointer& pChars, INT& pNumChars)"); 
	ValueIntData= dll.api("ValueIntData","INT( struct pVal, int& pData )");
	ValueIntDataSet = dll.api("ValueIntDataSet","INT( struct& pVal, int data, INT type, INT units )");
	ValueInt64Data = dll.api("ValueInt64Data","INT( struct pVal, long& pData )");
	ValueInt64DataSet = dll.api("ValueInt64DataSet","INT( struct &pVal, long data, INT type, INT units )");
	ValueTimeData = dll.api("ValueInt64Data","INT( struct pVal,struct& pData )");
	ValueTimeDataSet = dll.api("ValueInt64DataSet","INT( struct &pVal,INT lowData,INT highData, INT type, INT units )");
	ValueFloatData = dll.api("ValueFloatData","INT( struct pVal, double& pData )");
	ValueFloatDataSet = dll.api("ValueFloatDataSet","INT( struct &pVal, double data, INT type, INT units )");
	ValueBinaryData = dll.api("ValueBinaryData","INT( struct pVal,pointer& pBytes, INT& pnBytes )");
	ValueBinaryDataSet = dll.api("ValueBinaryDataSet","INT( struct &pVal,pointer pBytes, INT nBytes, INT type, INT units )");
	ValueToString = dll.api("ValueToString","INT( struct &pVal, INT how )");
	ValueFromString = dll.api("ValueFromString","INT( struct &pVal,string str,INT length,INT how)"); 
 	ValueElementsCount = dll.api("ValueElementsCount", "INT(struct pval,int &pn)"); 
 	ValueSetValueToKey = dll.api("ValueSetValueToKey", "INT(struct &pval,struct pkey, struct pval_to_set)"); 
 	ValueGetValueOfKey = dll.api("ValueGetValueOfKey", "INT(struct pval,struct pkey, struct& pretval)"); 
 	ValueNthElementValueSet = dll.api("ValueNthElementValueSet", "INT(struct &pval,int n,struct pval_to_set)"); 
 	ValueNthElementValue = dll.api("ValueNthElementValue", "INT(struct pval,int n, struct& pretval)");
 	ValueEnumElements = dll.api("ValueEnumElements", "INT(struct pval,pointer penum, pointer param)");
 	var fromUnicode = ..string.fromUnicode;
  	var toUnicode = ..string.toUnicode;
  	
  	VALUE_UNIT_TYPE = { 
  		"em";"ex";"pr";"sp";"";"";"px";"in";"cm";"mm";"pt";"pc";"dip";"";"color";"url";"symbol";
  		 ["in"]=8;pr=3;["%"]=3;sp=4;["%%"]=4;reserved3=14;em=1;cm=9;px=7;color=15;ex=2;symbol=65535;url=16;dip=13;pc=12;pt=11;mm=10
  	};
  	
	_metaProperty = ..util.metaProperty(
		_tonumber = function(){
			return tonumber( owner.value );
		}
		_tostring = function(){
			var val = owner.clone(); 
			val.stringify();
			var str = val.getString();
			val.clear();
			return str;
		}
		_eq = function(val){
			return ValueCompare(owner,val);
		} 
		clone = function(){
			var val = valueObject_t();
			ValueCopy(val,owner);
			return val;
		}
		clear = function(){
			if(owner.data) 
				ValueClear(owner);
		};
		getString = function(){ 
			var re,p, n = ValueStringData(owner, null, 0);
			if( re==0/*_HL_HV_OK*/  ){
				return (( p && n) ? fromUnicode(p,,true) : "");
			}
		}
		setString = function( v ){
			v = toUnicode(v); 
			return ValueStringDataSet(owner, v, #v/2, 0)==0/*_HL_HV_OK*/;  
		};
		getBinary = function(){
			var re,p,n = ValueBinaryData(owner,null,0);
			if(re==0/*_HL_HV_OK*/ && p){
				return ..raw.buffer(n,p);
			} 
		};
		setBinary = function(bin,len){
			ValueBinaryDataSet(owner,bin,len || #bin,0xC/*_HL_T_BYTES*/,0)   
		};
		getEle = function(){
			var re,p,n = ValueBinaryData(owner,null,0)
			if(re==0/*_HL_HV_OK*/ && p){
				return ..web.layout.element(p) ;
			}
		};
		getTime = function(){ 
			if( owner.type = 6/*_HL_T_DATE*/ ){
				var ftm = ..fsys.time();
				var re,v = ValueTimeData(owner, ftm);
				
				if(re==0/*_HL_HV_OK*/){ 
					if( owner.units & 0x10 )
						ftm.local();
						 
					var tm = ftm.toSystemTime(); 
					if( tm.year == 1601 )  tm.year = 1970;
					return tm;
				}
			}
		}
		setTime = function( v ){
			var ftm = ..fsys.time();
		
			if( ftm.fromSystemTime( v ) ) 
				ValueTimeDataSet(owner, ftm.dwLowDateTime,ftm.dwHighDateTime, 6/*_HL_T_DATE*/,0); 
		};
		getNumber = function(){ 
			var re,v = ValueFloatData(owner, 0); 
			if(re==0/*_HL_HV_OK*/)return v;
		}
		setNumber = function( v,units = 0 ){
			ValueFloatDataSet(owner, v, 4/*_HL_T_FLOAT*/, units);
		};
		getInt32 = function(){ 
			var re,v = ValueIntData(owner, 0); 
			if(re==0/*_HL_HV_OK*/)return v;
		}
		setInt32 = function( v,units = 0 ){
			ValueIntDataSet(owner, v, 3/*_HL_T_INT*/, units );
		};
		getLong64 = function(){ 
			var re,v = ValueInt64Data(owner, 0); 
			if(re==0/*_HL_HV_OK*/)return v;
		}
		setLong64= function( v,units = 0 ){
			ValueInt64DataSet(owner, v, 7/*_HL_T_CURRENCY*/, units); 
		};  
		getType = function(){
			var re,ht,units= ValueType( owner,0,0 ); 
			if( 0 == re ) return ht;
		}
		isDomObject = function(){
			var re,ht,units= ValueType( owner,0,0 ); 
			return ( 0 == re ) && ht == 0xE/*_HL_T_DOM_OBJECT*/;
		};
		isArray = function(){
			var re,ht,units= ValueType( owner,0,0 ); 
			return ( 0 == re ) && ht == 9/*_HL_T_ARRAY*/;
		};
		isMap = function(){
			var re,ht,units= ValueType( owner,0,0 ); 
			return ( 0 == re ) && ht == 0xA/*_HL_T_MAP*/;
		};
		getValue = function(){
			var re,ht,units= ValueType( owner,0,0 ); 
      		var unitName = VALUE_UNIT_TYPE[units]; 
      		
      		if( ht = 5/*_HL_T_STRING*/ ){
				return owner.getString();
			}
			elseif( ht = 4/*_HL_T_FLOAT*/ || ht == 8/*_HL_T_LENGTH*/){
				return owner.getNumber(),unitName;
			} 
			elseif( ht = 3/*_HL_T_INT*/ ){
				return owner.getInt32(),unitName; 
			}
			elseif( ht = 2/*_HL_T_BOOL*/ ){
				return !!owner.getInt32();
			}
			elseif( ht = 0xE/*_HL_T_DOM_OBJECT*/ ){
				return owner.getEle();
			}
			elseif( ht = 7/*_HL_T_CURRENCY*/ ){
				return owner.getLong64(),unitName;
			}
			elseif( ht = 6/*_HL_T_DATE*/ ){
				return owner.getTime();
			}
			elseif( ht = 0xA/*_HL_T_MAP*/ ){ 
				var m = {};
				owner.enum( 
    				function(k,v ){
    					m[k.getValue()] = v.getValue();
    				}
    			) 
    			return m;
			}
			elseif( ht = 9/*_HL_T_ARRAY*/ ){ 
				var m = {};
				var value = valueObject_t();
				for(i=1;owner.length;1){
					if( ValueNthElementValue(owner,i-1,value) == 0/*_HL_HV_OK*/ )
						m[i] = value.getValue(); 
				} 
    			return m;
			}
			elseif(  ht = 0xC/*_HL_T_BYTES*/ ){
      			return owner.getBinary();
      		}
		}
		setValue = function(v,units,dataType){
      		var ta = type(v); 
      		if( ta == "string" ){
      			owner.setString(v);
      		}
      		elseif( ta == "number" ){
      			if( type(units) == type.string ){
      				units = VALUE_UNIT_TYPE[units];
      			}; 
      			if( ! ( units && dataType) ){
      				var re,oldType,oldUnits= ValueType( owner,0,0 );
      				if(!units) units = oldUnits : 0;
      				
      				
      				if(!dataType){
      					if( oldType )
      						dataType = oldType;
      					else{
      						var n,f = ..math.modf(v);
      						dataType = f ? 4/*_HL_T_FLOAT*/ : 3/*_HL_T_INT*/; 
      					}
      				}
      			}

      			if( dataType == 3/*_HL_T_INT*/ ){
      				owner.setInt32(v,units)
      			}
      			elseif( dataType == 4/*_HL_T_FLOAT*/){
      				owner.setNumber(v,units)
      			}
      			else{
      				owner.setLong64(v,units)
      			} 
      		}
      		elseif( ta == "boolean" ){
      			ValueIntDataSet(owner, v?1:0, 2/*_HL_T_BOOL*/, 0); 
      		}
      		elseif( ta ==  "table" ){ 
      			
      			if( ( v@ == _metaProperty ) && ( v._struct == owner._struct ) ){
      				ValueCopy(owner,v);
      			}
      			elseif( ..time.istime(v) ){
      				owner.setTime( v );
      			}
      			else{
      				if( ..table.isArray(v) ){
      					for(i=1;#v;1){
      						ValueNthElementValueSet( owner,i-1,valueObject_t( v[i] ) );
      					} 
      				}
      				else {
      					for name,value in ..table.eachName(v){
      						ValueSetValueToKey(owner,valueObject_t(name),valueObject_t(value)); 
      					}
      				}
      			}
      		}
      		elseif( ta ==  "null" ){ 
      			ValueClear(owner);
      		}
      		elseif( ta  == "buffer" ){
      			owner.setBinary(v);
      		}
      		else {
      			error("错误的参数类型",2)
      		};
      	};
      	value = {
      		_get = function(){
      			return owner.getValue()
      		}
      		_set = function(v){
      			owner.setValue(v)
      		} 
      	}; 
		stringify = function(){
			ValueToString(owner,0/*_HL_CVT_SIMPLE*/);
			return owner.getString();
		}
		parse = function(str){
			str = toUnicode(str);
			return 0 == ValueFromString(owner,str,#str-2,0/*_HL_CVT_SIMPLE*/); 
		};
		jsonParse = function(str){
			str = toUnicode(str);
			return 0 == ValueFromString(owner,str,#str-2,1/*_HL_CVT_JSON_LITERAL*/);
		}
		jsonStringify = function(){
			ValueToString(owner,1/*_HL_CVT_JSON_LITERAL*/);
			return owner.getString();
		};
		length = {
			_get = function(){
				var ret,len = ValueElementsCount(owner,0);
				if( ret==0/*_HL_HV_OK*/)return len;
			} 
		}
		getItem = function(key){
			var retVal = valueObject_t();
			if(type(key)==type.number){
				if( ValueNthElementValue(owner,key-1,retVal) == 0/*_HL_HV_OK*/ )
					return retVal;
			}
			else {
				if( ValueGetValueOfKey(owner,valueObject_t(key),retVal) == 0/*_HL_HV_OK*/ )
					return retVal;
			} 
		};
		setItem = function(key,...){
			var val = valueObject_t(...);
			if(type(key)==type.number){
				return ( ValueNthElementValueSet(owner,key-1,val) == 0/*_HL_HV_OK*/ ) 
			}
			else {
				return ( ValueSetValueToKey(owner,valueObject_t(key),val) == 0/*_HL_HV_OK*/ ) 
			} 
		}; 
		enum = function(proc){
			var convert = ..raw.convert;
			var proc_c = ..raw.tostdcall(
				function(param,key,val){
					key = convert(key,valueObject_t() );
					val = convert(val,valueObject_t() );
					var ret = proc( key,val ); 
					return ret === null : ret;
				} ,"bool(pointer param,pointer key,pointer val)")
			ValueEnumElements(owner,proc_c);
		}
	);
	var _metaProperty = _metaProperty;
} 
 
var __valueObject_struct = valueObject.__valueObject_struct;
var _metaProperty = valueObject._metaProperty;

class valueObjectLite{
	ctor (v,...) {
		this = __valueObject_struct(); 
		this@ = _metaProperty;  
		
		if( v!==null ){
			this.setValue(v,...);
		}
	}; 
	clear = "disabled";
}

 /**intellisense()
web.layout.valueObjectLite() = 无GC值对象,避免自动释放,\n!web_layout_value.
web.layout.valueObject(.(初始值,单位,类型) = 创建并返回动态值类型,\n所有参数可选
web.layout.valueObject() = !web_layout_value.
!web_layout_value.getType() = 返回值类型 _HL_T_ 前缀常量表示
!web_layout_value.clone() = 复制值\n!web_layout_value.
!web_layout_value.addRef() = 添加引用计数
!web_layout_value.clear() = 清空值 
!web_layout_value.isDomObject() = 是否节点对象,\n使用 getEle()函数转换为节点对象
!web_layout_value.isArray() = 是否数组对象
!web_layout_value.isMap() = 是否键值表对象
!web_layout_value.getEle() = 返回节点对象,\n注意:节点类型只能读取不能写入
!web_layout_value.getString() = 返回字符串值\n如果值类型字符串值,取值返回空\n使用 tostring() 函数可强制返回数值
!web_layout_value.setString(__/*字符串值*/) = 写入字符串值
!web_layout_value.getTime() = 返回时间值\n如果值类型不是时间值,取值返回空
!web_layout_value.setTime(__/*时间值*/) = 写入时间值
!web_layout_value.getNumber() = 返回浮点数值\n如果值类型不是浮点数,取值返回空\n使用 tonumber() 函数可强制返回数值
!web_layout_value.setNumber(__/*数值*/) = 写入浮点数值
!web_layout_value.getInt32() = 返回整型数值\n如果值类型不是整型值,取值返回空
!web_layout_value.setInt32(__/*数值*/) = 写入整型数值
!web_layout_value.getLong64() = 返回长整型数值\n如果值类型不是长整型数值,取值返回空
!web_layout_value.setLong64(__/*数值*/) = 写入长整型数值 
!web_layout_value.getValue() = 返回字符串值、数值、时间值
!web_layout_value.setValue(.(值,单位,类型) = 写入字符串值、数值、时间值\n参数2,参数3为可选参数
!web_layout_value.getBinary() = 返回 buffer 类型字节数组\n零长度数组返回 null
!web_layout_value.setBinary(.(buffer,len) = 设置二进制字节数组,\n如果参数@1是buffer、字符串,可选用参数@2指定长度,\n如果参数@1是指针,则必须指定长度 
!web_layout_value.length = 数组长度
!web_layout_value.value = 读取或写入字符串值、数值、时间值
!web_layout_value.stringify() = 转换并返回字符串
!web_layout_value.parse(.("10pt") = 解析字符串
!web_layout_value.jsonStringify() = 转换并返回JSON字符串
!web_layout_value.jsonParse(.('{ k:"v" }') = 解析JSON字符串
!web_layout_value.getItem(.(索引) = 获取成员
!web_layout_value.setItem(.(索引,值) = 设置成员值
!web_layout_value.getItem() = !web_layout_value.
!web_layout_value.enum(枚举函数) = @.enum( \n	function(k,v ){\n		io.print( k,v ) \n	}\n)
_HL_CVT_SIMPLE=@0/*_HL_CVT_SIMPLE*/
_HL_CVT_JSON_LITERAL=@1/*_HL_CVT_JSON_LITERAL*/
_HL_CVT_JSON_MAP=@2/*_HL_CVT_JSON_MAP*/
end intellisense**/