﻿//-----------------------------------------------------------------------------
// XObject
//
// Copyright 2005-2010 - Xcential Group LLC.
//
//-----------------------------------------------------------------------------

//=============================================================================
// Constructor

function XObject(
   item,
   create
)
{
   item = (item == null) ? null : item;
   create = (create == null) ? true : false;

   if (create)
      return new XObject(item, false);

   //--------------------------------------------------------------------------
   // Private Interface

   //--------------------------------------------------------------------------
   // Privileged Interface

   this.valueOf = function()
   {

      return oItem;
   }

   //--------------------------------------------------------------------------
   // Initialization

   var oItem = item;

}

XObject.prototype.objectClass = "XObject";

//=============================================================================
// Static Interface

XObject.isNothing = function(
   what
)
{
   what = (what == null) ? null : what;

   if (what == null)
      return true;

   switch (typeof(what))
   {
      case "string":
         return (what.length == 0) ? true : false;
         break;
      case "number":
         return (what == 0) ? true : false;
         break;
      case "boolean":
         return (what == false) ? true : false;
         break;
      case "function":
         return XObject.isNothing(value());
         break;
      case "object":
         try
         {
            // Note: Associative arrays will return a value of zero although
            //       they may contain items. Concatenating the contents of
            //       an associative array as a string will test for content
            //       in this case. However, objects that return a length of
            //       zero should still be considered to be nothing.
            if (what.length == 0)
            {
               var value = what.toString();
               if (value == "[object]")
                  return true;
               var count = 0;
               for (key in what)
                  count++;
               return (count == 0) ? true : false;
            }
         }
         catch (error)
         {
            try
            {
               what = what.toString();
               if (what.length == 0)
                  return true;
            }
            catch (error)
            {
               return true;
            }
         }
         return false;
         break;
   }

   return false;
}

//-----------------------------------------------------------------------------

XObject.isSomething = function(
   what
)
{

   return !XObject.isNothing(what);
}

//=============================================================================
// Public Interface

XObject.prototype.toString = function()
{

   var value = this.valueOf();

   if (value == null)
      return "{null}";

   switch (typeof(value))
   {
      case "string":
         return value;
         break;
      case "number":
         return String(value).toString();
         break;
      case "boolean":
         return (value) ? "true" : "false";
         break;
      case "function":
         try
         {
            return XObject(value()).toString();
         }
         catch (error)
         {
            return "{function}";
         }
         break;
      case "object":
         var stringValue = "{object}";
         try
         {
            stringValue = "[";
            for (var i=0; i<value.length; i++)
            {
               if (value[i] == null)
                  stringValue += "null,";
               else if (typeof(value[i]) == "string")
                  stringValue += "'" + value[i] + "',";
               else
                  stringValue += value[i].toString() + ",";
            }
            stringValue += "]";
            stringValue = stringValue.replace(/,\]$/, "]");
            return stringValue;
         }
         catch (error)
         {
            try
            {
               stringValue = value.toString();
            }
            catch (error)
            {
               stringValue = "{object}";
            }
            var stringValue;
         }
         break;
   }

   return "{unknown}";
}

//-----------------------------------------------------------------------------

XObject.prototype.length = function()
{

   var value = this.valueOf();

   if (value == null)
      return null;

   var length = 0;
   try
   {
      length = value.length;
   }
   catch (error)
   {
      length = 0;
   }

   return length;
}

//-----------------------------------------------------------------------------

XObject.prototype.exists = function()
{

   var value = this.valueOf();

   if (value == null)
      return false;

   return true;
}

//-----------------------------------------------------------------------------

XObject.prototype.isNull = function()
{

   var value = this.valueOf();

   if (value == null)
      return true;

   return false;
}

//-----------------------------------------------------------------------------

XObject.prototype.isSomething = function()
{

   var value = this.valueOf();

   return XObject.isSomething(value);
}

//-----------------------------------------------------------------------------

XObject.prototype.isNothing = function()
{

   return !this.isSomething();
}

//-----------------------------------------------------------------------------

XObject.prototype.isEmpty = function()
{

   var value = this.valueOf();

   if (value == null)
      return true;

   switch (typeof(value))
   {
      case "string":
         return (value.length > 0) ? false : true;
         break;
      case "number":
         return (value == 0) ? true : false;
         break;
      case "boolean":
         return false;
         break;
      case "function":
         try
         {
            return XObject(value()).isEmpty();
         }
         catch (error)
         {
            return false;
         }
         break;
      case "object":
         try
         {
            return (value.length > 0) ? false : true
         }
         catch (error)
         {
            return false;
         }
         break;
   }

   return true;
}

//-----------------------------------------------------------------------------

XObject.prototype.hasContent = function()
{

   var value = this.valueOf();

   if (value == null)
      return false;

   switch (typeof(value))
   {
      case "string":
         return (value.length > 0) ? true : false;
         break;
      case "number":
         return (value == 0) ? false : true;
         break;
      case "boolean":
         return true;
         break;
      case "function":
         try
         {
            return XObject(value()).hasContent();
         }
         catch (error)
         {
            return true;
         }
         break;
      case "object":
         try
         {
            return (value.length > 0) ? true : false;
         }
         catch (error)
         {
            return true;
         }
         break;
   }

   return false;
}

//=============================================================================


