
//<script>

function TypeDesc(){};
register( TypeDesc );
Lib.create( TypeDesc );

TypeDesc.addMethod(

  'from',
  function /* from */( validator, cality, type, strict, range, def )
  {
    if ( Lib.constructorOf( validator ) == TypeDesc )
      return validator;
    var tmp;
    var result = new TypeDesc();
    result.setCality( cality );
    tmp = result.setType( type );
    if ( tmp == Lib.NOTVALID )
      alert( 'invalid TypeDesc' );
    result.setStrict( strict );
    tmp = result.setRange( range );
    if ( tmp == Lib.NOTVALID )
      alert( 'invalid TypeDesc' );
    result.setDef( def );
    result.setValidator( validator );
    return result;
  },

  'updateType',
  function /* updateType */( context )
  {
    var props = TypeDesc.getProps();    var prop = props.type;
    var range = Lib.M( top.__cNames );
/*
    for ( var i in context )
    {
      if ( typeof( context[ i ] ) == 'function' )
        range[ range.length ] = Lib.nameOf( context[ i ] );
    }
*/
    prop.setRange( range );
  }

);

TypeDesc.prototype.setValidator =
function /* setValidator */( v )
{
  this._v0 = v;
  return this.getValidator();
}

TypeDesc.prototype.getValidator =
function /* getValidator */()
{
  if ( !this._v0 )
  {
    var c = this.getCality();
    var t = this.getType();
    var s = this.getStrict();

    var result = '/*gen*/if ( !Lib.validator.validate( a, '
    + ( Util.isAny( c ) ? c : 'null' ) + ', ';

    if ( !Util.isAny( t ) )
      result += 'null';
    else if ( !Lib.isMulti( t ) )
    {
      result += '\'' + t + '\'';
    }
    else
    {
      result += 'Lib.M([';
      for ( var i = 0; i < t.length; i++ )
      {
        if ( i > 0 )
          result += ', ';
        result += '\'' + t[ i ] + '\'';
      }
      result += '])';
    }
    result += ', ';
    
    result += ( Util.isAny( s ) ? s : 'null' ) + ' ) ) return Lib.NOTVALID' +
    '';
    this._v0 = result;
  }
  return this._v0;
}

TypeDesc.prototype.setCality =
function /* setCality */( c )
{
  c = parseInt( c );
  if ( isNaN( c ) )
    return Lib.NOTVALID;
  if ( c < Lib.ZERO || c > Lib.ONEORN )
    return Lib.NOTVALID;
  this._c1 = c;
  return this.getCality();
}

TypeDesc.prototype.getCality =
function /* getCality */()
{
  return this._c1;
}

TypeDesc.prototype.setType =
function /* setType */( t )
{
  var vt;
  if ( Util.isAny( t ) )
  {
    if ( Lib.isMulti( t ) )
    {
      for ( var i = 0; i < t.length; i++ )
      {
        eval( 'vt = ' + t[ i ] + ';' );
        if ( typeof( vt ) != 'function' )
          return Lib.NOTVALID;
      }
    }
    else
    {
      eval( 'vt = ' + t + ';' );
      if ( typeof( vt ) != 'function' )
        return Lib.NOTVALID;
    }
  }
  this._t2 = t;
  return this.getType();
}

TypeDesc.prototype.getType =
function /* getType */()
{
  return this._t2;
}

TypeDesc.prototype.initType =
function /* initType */( force )
{
  var result = Lib.M( [] );
  if ( force )
    this._t2 = result;
  return result;
}

TypeDesc.prototype.setStrict =
function /* setStrict */( s )
{
  this._s3 = s;
  return this.getStrict();
}

TypeDesc.prototype.getStrict =
function /* getStrict */()
{
  return this._s3;
}

TypeDesc.prototype.setRange =
function /* setRange */( r )
{
  if ( Util.isAny( r ) && !Lib.isMulti( r ) )
    return Lib.NOTVALID;
  this._r4 = r;
  return this.getRange();
}

TypeDesc.prototype.getRange =
function /* getRange */()
{
  return this._r4;
}

TypeDesc.prototype.initRange =
function /* initRange */( force )
{
  var result = Lib.M( [] );
  if ( force )
    this._r4 = result;
  return result;
}

TypeDesc.prototype.setDef =
function /* setDef */( d )
{
  this._d5 = d;
  return this.getDef();
}

TypeDesc.prototype.getDef =
function /* getDef */()
{
  return this._d5;
}

TypeDesc.prototype.asString =
function /* asString */()
{
  var result;
  result = 'TypeDesc.from( ';

  var valid = this.getValidator();
  if ( valid == Lib.NOVALIDATOR )
    result += 'Lib.NOVALIDATOR';
  else if ( valid.indexOf( '/*gen*/' ) == 0 )
    result += 'null';
  else
    result += '\'' + valid + '\'';

  result += ', ';
  var cality = this.getCality();
  if ( Util.isAny( cality ) )
    result += ( ( cality == Lib.ZERO ) ? 'Lib.ZERO' : ( ( cality == Lib.ONE ) ? 'Lib.ONE' : ( ( cality == Lib.ZEROORN ) ? 'Lib.ZEROORN' : 'Lib.ONEORN' ) ) );
  else
    result += 'null';

  result += ', ';
  var type = this.getType();
  if ( Util.isAny( type ) )
  {
    if ( Lib.isMulti( type ) )
    {
      result += 'Lib.M( [ ';
      for ( var i = 0; i < type.length; i++ )
      {
        if ( i > 0 )
          result += ', ';
        result += '\'' + type[ i ] + '\'';
      }
      result += ' ] )';
    }
    else
    {
      result += '\'' +  type + '\'';
    }
  }
  else
    result += 'null';

  result += ', ';
  var strict = this.getStrict();
  if ( Util.isAny( strict ) )
    result += ( ( strict == Lib.CANNOTCAST ) ? 'Lib.CANNOTCAST' : 'Lib.CANCAST' );
  else
    result += 'null';

  result += ', ';
  var range = this.getRange();
  if ( Lib.isMulti( range ) )
  {
    result += 'Lib.M( [ ';
    for ( var i = 0; i < range.length; i++ )
    {
      if ( i > 0 )
        result += ', ';
      result += '"' +  range[ i ] + '"';
    }
    result += ' ] )';
  }
  else
    result += 'null';

  result += ', ';
  var def = this.getDef();
  if ( Util.isAny( def ) )
    result += '\"' + def + '\"';
  else
    result += 'null';

  result += ' )';
  return result;
}

function PropDesc(){};
register( PropDesc );
Lib.create( PropDesc );

PropDesc.addMethod(

  'from'
  ,function /* from */( name, ifNull, validator, range )
  {
    if ( Lib.constructorOf( name ) == PropDesc )
      return name;
    var result = new PropDesc();
    result.setName( name );
    var tdesc;
    if ( Lib.constructorOf( ifNull ) != TypeDesc )
      tdesc = TypeDesc.from( ( validator ? validator : Lib.NOVALIDATOR ), null, null, null, range, ifNull );
    else
    {
      if ( arguments.length > 2 )
      {
        tdesc = Lib.M( [] );
        for ( var i = 1; i < arguments.length; i++ )
          tdesc[ tdesc.length ] = arguments[ i ];
      }
      else
        tdesc = ifNull;
    }
    result.setTypeDesc( tdesc );
    return result;
  }

);

PropDesc.prototype.asString =
function /* asString */()
{
  var result = '';
  var n = this.getName();
  var t, tt = this.getTypeDesc();
  if ( !Lib.isMulti( tt ) )
    tt = [ tt ];
  for ( var i = 0; i < tt.length; i++ )
  {
    t = tt[ i ];
    t = t.asString();
    if ( t != 'TypeDesc.from( Lib.NOVALIDATOR, null, null, null, null, null )' )
    {
      result += ', ' + t;
    }
  }
  if ( result )
  {
    result = 'PropDesc.from( ' + '\'' + n + '\'' + result + ' )';
  }
  else
    result = '\'' + n + '\'';

  return result;
}

PropDesc.prototype.setName =
function /* setName */( n )
{
  this['_n0'] = n;
  return this.getName();
}

PropDesc.prototype.getName =
function /* getName */()
{
  return this._n0;
}

PropDesc.prototype.setIfNull =
function /* setIfNull */( ifn )
{
  var td = this.getTypeDesc();
  return td.setDef( ifn );
}

PropDesc.prototype.getIfNull =
function /* getIfNull */()
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.getDef();
}

PropDesc.prototype.setTypeDesc =
function /* setTypeDesc */( t )
{
  this._t2 = t;
  return this.getTypeDesc();
}

PropDesc.prototype.getTypeDesc =
function /* getTypeDesc */()
{
  if ( !this._t2 )
  {
    this._t2 = TypeDesc.from();
  }
  return this._t2;
}

PropDesc.prototype.setValidator =
function /* setValidator */( v )
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.setValidator( v );
}

PropDesc.prototype.getValidator =
function /* getValidator */()
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.getValidator();
}

PropDesc.prototype.setRange =
function /* setRange */( v )
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.setRange( v );
}

PropDesc.prototype.getRange =
function /* getRange */()
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.getRange();
}

PropDesc.prototype.setCality =
function /* setCality */( v )
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.setCality( v );
}

PropDesc.prototype.getCality =
function /* getCality */()
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.getCality();
}

PropDesc.prototype.getType =
function /* getType */()
{
  var td = this.getTypeDesc();
  if ( Lib.isMulti( td ) )
    td = td[ 0 ];
  return td.getType();
}

PropDesc.prototype.setUn =
function /* setUn */( u )
{
  this._u1 = u;
  return this.getUn();
}

PropDesc.prototype.getUn =
function /* getUn */()
{
  return this._u1;
}

PropDesc.prototype.setupUniqueName =
function /* setupUniqueName */( o )
{
  var n = this.getName();
  var result = '_' + n.charAt( 0 );
  result += o[ Lib.COUNTVAR ];
  o[ Lib.COUNTVAR ] = o[ Lib.COUNTVAR ] + 1;
  this.setUn( result );
  return result;
}

Lib.__addToProps( PropDesc
  ,PropDesc.from( 'name', TypeDesc.from( Lib.NOVALIDATOR, Lib.ONE, 'String' ) )
  ,PropDesc.from( 'un', TypeDesc.from( Lib.NOVALIDATOR, Lib.ONE, 'String' ) )
  ,PropDesc.from( 'typeDesc', TypeDesc.from( Lib.NOVALIDATOR, Lib.ONEORN, 'TypeDesc', Lib.CANNOTCAST ) )
);

Lib.__addToProps( TypeDesc
  ,PropDesc.from( 'validator', TypeDesc.from( Lib.NOVALIDATOR, Lib.ZERO, 'String' ) )
  ,PropDesc.from( 'cality', TypeDesc.from( Lib.NOVALIDATOR, Lib.ZERO, 'Number', null, Lib.M( [ 'Lib.ZERO', 'Lib.ONE', 'Lib.ZEROORN', 'Lib.ONEORN' ] ) ) )
  ,PropDesc.from( 'type', TypeDesc.from( Lib.NOVALIDATOR, Lib.ZERO, 'String', Lib.CANCAST ) )
  ,PropDesc.from( 'strict', TypeDesc.from( Lib.NOVALIDATOR, Lib.ZERO, 'Boolean' ) )
  ,PropDesc.from( 'range', TypeDesc.from( null, Lib.ZEROORN, 'String' ) )
  ,PropDesc.from( 'def', TypeDesc.from( Lib.NOVALIDATOR, Lib.ZERO, 'String' ) )
);
