
//<script>

Lib.fromGetterName =
function /* fromGetterName */( gn )
{
  var result = null;
  var i = gn.indexOf( 'get' ) + 3;
  if ( i == 3 )
  {
    result = Lib.unCapitalizeName( gn.substr( i ) );
  }
  return result;
}

Lib._$numbers = '0123456789';

Lib.fromPropName =
function /* fromPropName */( pn, method )
{
  var result;
  method = Util.get_if_ok( method, 'get' );
  if ( Lib._$numbers.indexOf( pn.charAt( 0 ) ) == -1 ){
    result = method + Lib.capitalizeName( pn );
  }
  return result;
}

/** deprecated **/
Lib.setterFromPropName =
function( pn )
{
  var result;
  if ( Lib._$numbers.indexOf( pn.charAt( 0 ) ) == -1 )
    result = 'set' + Lib.capitalizeName( pn );
  return result;
}

Lib.init =
function /* init */( o, p, flag, ret )
{
  var result = Lib.NOTVALID;
  var oTmp;
  flag = Util.get_if_ok( flag, Lib.INIT_FACTORY );
  if ( o )
  {
    var s = p.split( '.' );
    if ( s.length > 1 )
    {
      oTmp = Lib.get( o, s.slice( 0, s.length - 1 ).join( "." ) );
      p = s[ s.length - 1 ];
    }
    else
    {
      oTmp = o;
    }
  }
  if ( oTmp )
  {
    var itter = Lib.fromPropName( p, 'init' );
    if ( oTmp[ itter ] )
    {
      result = oTmp[itter]( flag, ret );
    }
    else
    {
      result = ret ? ret : {};
      if( flag == Lib.INIT_SET )
        oTmp[ p ] = result;
    }
  }
  return result;
}

Lib.get =
function /* get */( o, p )
{
  var result = o;
  var s = p.split( '.' );
  var n, pn;
  for( var i in s )
  {
    if ( !result )
    {
      break;
    }
    pn = s[ i ];
    n = this.fromPropName( pn, 'get' );
    if ( result[ n ] )
    {
      result = result[ n ]();
    }
    else
    {
      result = result[ pn ];
    }
  }
  return result;
}

Lib.set =
function /* set */( o, p, v, forceCreation )
{
  forceCreation = Util.get_if_ok( forceCreation, Lib.NOFORCE );
  var tmp, prevResult, result = Lib.NOTVALID;
  if( o )
  {
    result = o;
    var s = p.split( '.' );
    var n, pn, prevPn, prevCreated, prevType, isN, ret, clty, t, ind;

    for ( var i = 0; i < s.length - 1; i++ )
    {
      if ( !result )
        break;
      pn = s[ i ];
      tmp = Lib.get( result, pn );
      if ( !tmp )
      {
        if ( forceCreation == Lib.FORCE )
        {
          ret = t = null;
          isN = ( '0123456789'.indexOf( pn.charAt( 0 ) ) != -1 );
          if ( prevPn && ( prevCreated == prevPn ) )
          {
            if ( isN )
            {
              clty = Lib.calityOf( prevResult, prevPn );
              if ( ( clty == Lib.ZEROORN ) || ( clty == Lib.ONEORN ) )
                result = Lib.M( [] );
              else
                result = [];
              result = Lib.set( prevResult, prevPn, result );
              if ( result == Lib.NOTVALID )
                return result;
              ret = null;
            }
          }
          if ( isN )
          {
            if ( prevType )
              t = prevType;
            else
            { 
              t = Lib.libTypeOf( prevResult, prevPn );
            }
          }
          else  
            t = Lib.libTypeOf( result, pn );
          if ( t )
          {
            ret = Lib.newInstance( t );
          }
          tmp = Lib.init( result, pn, Lib.INIT_SET, ret );
          if ( result == Lib.NOTVALID )
            return result;
          prevCreated = pn;
          prevType = t;
        }
      }
      else
      {
        prevCreated = prevType = null;
      }
      prevResult = result;
      prevPn = pn;
      result = tmp;
    }

    if ( !result )
    {
      result = Lib.NOTVALID;
    }
    else
    {
      pn = s[ i ];
      if ( prevPn && ( prevCreated == prevPn ) )
      {
        isN = ( '0123456789'.indexOf( pn.charAt( 0 ) ) != -1 );
        if ( isN )
        {
          clty = Lib.calityOf( prevResult, prevPn );
          if ( ( clty == Lib.ZEROORN ) || ( clty == Lib.ONEORN ) )
            ret = Lib.M( [] );
          else
            ret = [];
          result = Lib.set( prevResult, prevPn, ret );
          if ( result == Lib.NOTVALID )
            return result;
        }
      }
      n = this.fromPropName( pn, 'set' );
      if ( result[ n ] )
      {
        result = result[ n ]( v );
      }
      else
      {
        result = result[ pn ] = v;
      }
    }
  }
  return result;
}

Lib.parentOf =
function /* parentOf */( o )
{
  var result;
  if ( !o || o == Object )
    result = null;
  else
  {
    if ( o.getParent )
    {
      result = o.getParent();
    }
    else
    {
      if ( o.prototype )
        result = o.prototype.constructor;
      else
        result = null;
    }
    if ( result == o )
      result = Object;
  }
  return result;
}

Lib.classesOf =
function /* classesOf */( o )
{
  var c = Lib.constructorOf( o );
  var result;
  if ( c )
  {
    if ( c == Object )
      result = [ c ];
    else
    {
      result = [ c ];
      while ( ( c = Lib.parentOf( c ) ) != Object )
      {
        result[ result.length ] = c;
      }
      result.reverse();
    }
  }
  return result;
}

Lib.classFromPropertyName =
function /* classFromPropertyName */( o, pn )
{
  var props, c, cls;
  if ( Lib.isLibbed( o ) )
  {
    cls = Lib.classesOf( o );
    for ( var i = 0; i < cls.length; i++ )
    {
      c = cls[ i ];
      props = c.getProps();
      if ( props[ pn ] )
        return c;
    }
  }
  return c;
}

Lib.nameOf =
function /* nameOf */( c )
{
  var result;
  if ( c == null )
    return 'null';
  if ( typeof( c ) == 'undefined' )
    return 'undefined';
  if ( typeof( c ) != 'function' )
    return 'not a constructor';
  if ( c.getName )
  {
    result = c.getName();
  }
  else
  {
/*
    if ( c == String )
      result = 'String';
    else if ( c == Number )
      result = 'Number';
    else if ( c == Boolean )
      result = 'Boolean';
    else if ( c == Array )
      result = 'Array';
    else if ( c == Date )
      result = 'Date';
    else if ( c == Math )
      result = 'Math';
    else if ( c == RegExp )
      result = 'RegExp';
    else if ( c == Function )
      result = 'Function';
    else
      result = 'Object';
*/
    result = Util.getFunctionName( c );
  }
  return result;
}

Lib.constructorOf =
function /* constructorOf */( o )
{
  var result;
  if ( Util.isAny( o ) )
  {
    if ( o.getConstructor )
    {
      result = o.getConstructor();
    }
    else
    {
      if ( o.constructor )
        result = o.constructor;
    }
  }
  return result;
}

Lib.constructorNameOf =
function /* constructorNameOf */( o )
{
  var c = Lib.constructorOf( o );
  if ( c )
    return Lib.nameOf( c );
  else
    return '';
}

Lib.isLibbed =
function /* isLibbed */( o )
{
  var libbed = false;
  if ( Util.isAny( o ) && o.getConstructor )
    libbed = true;
  return libbed;
}

Lib.getPrivateNameOf =
function /* getPrivateNameOf */( o, pn )
{
  var result, c, props;
  if ( Lib.isLibbed( o ) )
  {
    c = Lib.constructorOf( o );
    props = c.getProps();
    if ( props[ pn ] )
      result = props[ pn ].getUn();
  }
  return result;
}

Lib.isPrivate =
function /* isPrivate */( o, pn )
{
  var result = false, i, c, prop, props, n;
  if ( Lib.isLibbed( o ) )
  {
    if ( pn.indexOf( Lib.PRIVATEPRE ) == 0 )
      result = true
    else
    {
      c = Lib.constructorOf( o );
      props = c.getProps();
      for ( var i in props )
      {
        if ( i == Lib.PROPLISTVAR ) continue;
        prop = props[ i ];
        if ( prop.getUn() == pn )
        {
          result = true;
          break;
        }
      }
    }
  }
  return result;
}

Lib.rangeOf =
function /* rangeOf */( o, pn )
{
  var result, c, props, td, tmp, evaled;
  if ( Lib.isLibbed( o ) )
  {
    c = Lib.constructorOf( o );
    props = c.getProps();
    if ( props[ pn ] )
    {
      td = props[ pn ].getTypeDesc();
      if ( !Lib.isMulti( td ) )
        td = [ td ];
      for ( var i = 0; i < td.length; i++ )
      {
        if ( !result )
          result = {};
        result[ td[ i ].getType() ] = td[ i ].getRange();
      }
    }
    if ( result )
    {
      var r;
      for ( var i in result )
      {
        r = result[ i ];
        if ( !r ) continue;
        //if ( !td._$_evaled )
        //{
          evaled = Lib.M( [] );
          for ( var j = 0; j < r.length; j++ )
          {
            eval( 'tmp=' + r[ j ] );
            evaled[ j ] = tmp;
          }
          //td._$_evaled = true;
          //td._$_evaledR = evaled;
        //}
        //else
          //evaled = td._$_evaledR;
        result[ i ] = evaled;
      }
    }
  }
  return result;
}

Lib.calityOf =
function /* calityOf */( o, pn )
{
  var result, c, props;
  if ( Lib.isLibbed( o ) )
  {
    c = Lib.constructorOf( o );
    props = c.getProps();
    if ( props[ pn ] )
      result = props[ pn ].getCality();
  }
  return result;
}

Lib.libTypeOf =
function /* libTypeOf */( o, pn )
{
  var result, c, props;
  if ( Lib.isLibbed( o ) )
  {
    c = Lib.constructorOf( o );
    props = c.getProps();
    if ( props[ pn ] )
    {
      result = props[ pn ].getType();
      if ( Lib.isMulti( result ) )
        result = result[ 0 ];
    }
  }
  if ( result )
  {
    eval( 'result = ' + result + ';' );
  }
  return result;
}

Lib.getProps =
function /* getProps */( o )
{
  var result = Lib.emptyArray, c;
  if ( Lib.isLibbed( o ) )
  {
    c = Lib.constructorOf( o );
    result = c.getProps();
  }
  return result;
}

Lib.emptyArray = [];
Lib.DEFPROPS = {
  Array: Lib.emptyArray
  ,Boolean: Lib.emptyArray
  ,Boolean: Lib.emptyArray
  ,Date: [ 'date', 'month', 'fullYear', 'hours', 'minutes', 'day', 'seconds', 'milliseconds', 'year', 'time' ]
  ,Math: Lib.emptyArray
  ,Number: Lib.emptyArray
  ,RegExp: Lib.emptyArray
  ,String: Lib.emptyArray
}

Lib.getProperties =
function /* getProperties */( o, func )
{
  var result = [];
  if ( typeof( o ) != 'undefined' && o != null && o.constructor  )
  {
    var pn, props, c = Lib.constructorOf( o );
    var cn = Lib.nameOf( c );
    var tmp = Lib.DEFPROPS[ cn ];
    if ( tmp )
      return tmp;

    if ( Lib.isLibbed( o ) )
    {
      props = c.getProps();
      result = Lib.clone( props[ Lib.PROPLISTVAR ] );
    }

    for ( var i in o )
    {
      if ( Util.isFunction( o[ i ] ) && !func )
        continue;
      if ( Lib.isPrivate( o, i ) )
        continue;
      result[ result.length ] = i;
    }

  }
  return result;
}

