﻿//-----------------------------------------------------------------------------
// XArray
//
// Copyright 2005-2010 - Xcential Group LLC.
//
//-----------------------------------------------------------------------------

XArray.prototype = new XObject;
XArray.prototype.constructor = XArray;

//=============================================================================
// Constructor

function XArray(
   array,
   create
)
{
   array = (array == null) ? null : array;
   create = (create == null) ? true : false;

   if (create)
      return new XArray(array, false);

   //--------------------------------------------------------------------------
   // Private Interface

   //--------------------------------------------------------------------------
   // Privileged Interface

   this.valueOf = function()
   {

      return oArray;
   }

   //--------------------------------------------------------------------------

   this.setObjectValue = function(
      array
   )
   {
      array = (array == null) ? null : array;

      oArray = XArray.toArray(array);

      return oArray;
   }

   //--------------------------------------------------------------------------
   // Initialization

   var oArray = this.setObjectValue(array);

}

XArray.prototype.objectClass = "XArray";

//=============================================================================
// Static Interface

XArray.STYLE_ARRAY             = "array";
XArray.STYLE_COMMA_SEPARATED   = "comma_separated";
XArray.STYLE_COMMA_SENTENCE    = "comma_sentence";

XArray.SORT_ASCENDING          = "asc";
XArray.SORT_DESCENDING         = "desc";

//-----------------------------------------------------------------------------

XArray.toArray = function(
   value
)
{
   value = (value == null) ? null : value;

   if (value == null)
      return [];

   switch (typeof(value))
   {
      case "string":
         var array = [];
         if ((/^\s*\[/).test(value) && (/\]\s*$/).test(value))
         {
            array = eval(value);
         }
         else
         {
            value = XString.normalize(value);
            array = value.split(" ");
         }
         return array;
         return
      case "number":
         return [value];
         break;
      case "boolean":
         return [value];
         break;
      case "function":
         try
         {
            return [value()];
         }
         catch (error)
         {
            return [value];
         }
         break;
      case "object":
         try
         {
            if (value.length >= 0)
               return value;
            else
               return value.toArray();
         }
         catch (error)
         {
            return [value];
         }
         break;
   }

   return [];
}

//=============================================================================
// Public Interface

XArray.prototype.toString = function(
   style
)
{
   style = (style == null) ? XArray.STYLE_ARRAY : style;

   var array = this.valueOf();
   var text = "";
   switch (style)
   {
      case XArray.STYLE_ARRAY:
         text = "[";
         for (var i=0; i<array.length; i++)
         {
            var value = array[i];
            if (value == null)
            {
               text += "null" + ",";
               continue;
            }
            switch (typeof(value))
            {
               case "string":
                  text += "'" + value.replace(/\'/g, "\\'") + "'" + ",";
                  break;
               case "number":
                  text += String(value).toString() + ",";
                  break;
               case "boolean":
                  text += ((value) ? "true" : "false") + ",";
                  break;
               case "function":
                  try
                  {
                     text += value() + ",";
                  }
                  catch (error)
                  {
                     text += "[function]" + ",";
                  }
                  break;
               case "object":
                  try
                  {
                     text += XArray(value).toString(style) + ",";
                  }
                  catch (error)
                  {
                     text += "[object]" + ",";
                  }
                  break;
            }
         }
         text += "]";
         text = text.replace(/,\]$/, "]");
         break;
      case XArray.STYLE_COMMA_SEPARATED:
         text = XString.getStringFrom(array).replace(/,\s*/g, ", ") ;
         break;
      case XArray.STYLE_COMMA_SENTENCE:
         for (var i=0; i<array.length; i++)
         {
            text += XString.getStringFrom(array[i]);
            text += ((i+1<array.length) ? ((array.length > 2) ? ", " : " ") : "");
            text += ((i+2==array.length) ? "and " : "");
         }
         break;
   }

   return text;
}

//-----------------------------------------------------------------------------

XArray.prototype.length = function()
{

   return this.valueOf().length;
}

//-----------------------------------------------------------------------------

XArray.prototype.toArray = function()
{

   return this.valueOf();
}

//-----------------------------------------------------------------------------

XArray.prototype.contains = function(
   value
)
{

   var items = this.valueOf();
   for (var i=0; i<items.length; i++)
   {
      var item = items[i];
      if (item == value)
         return true;
   }

   return false;
}

//-----------------------------------------------------------------------------

XArray.prototype.compress = function()
{
   var newItems = [];

   var items = this.valueOf();
   for (var i=0; i<items.length; i++)
   {
      var item = items[i];
      if (item)
         newItems.push(item);
   }

   return this.setObjectValue(newItems);
}

//-----------------------------------------------------------------------------

XArray.prototype.clone = function()
{
   var newItems = [];

   var items = this.valueOf();
   for (var i=0; i<items.length; i++)
   {
      var item = items[i];
      newItems.push(item);
   }

   for (key in items)
   {
      newItems[key] = items[key];
   }

   return newItems;
}

//-----------------------------------------------------------------------------

XArray.prototype.slice = function(
   startIndex,
   length
)
{
   startIndex = (startIndex == null) ? 0 : startIndex;
   length = (!length || length == 0) ? null : length;

   var items = this.valueOf();

   if (length)
      slice = items.slice(startIndex, startIndex + length);
   else
      slice = items.slice(startIndex);

   return slice;
}

//-----------------------------------------------------------------------------

XArray.prototype.sort = function(
   sortName,
   sortDir
)
{
   sortDir = (sortDir == null) ? XArray.SORT_ASCENDING : sortDir;

   function sortCompare(
      item1,
      item2
   )
   {

      var attribute = (XString(XArray.sortName).isSomething()) ? XArray.sortName : "id";
      var dir = (XString(XArray.sortDir).isSomething()) ? XArray.sortDir : XArray.SORT_ASCENDING;

      var val1 = (item1[attribute]) ? item1[attribute] : "";
      var val2 = (item2[attribute]) ? item2[attribute] : "";

      if (dir == XArray.SORT_ASCENDING)
      {
         if (val1 > val2) return 1;
         if (val1 < val2) return -1;
      }
      else
      {
         if (val1 > val2) return -1;
         if (val1 < val2) return 1;
      }

      return 0;
   }

   var items = this.valueOf();

   XArray.sortName = sortName;
   XArray.sortDir = sortDir;

   items.sort(sortCompare);

   return items;
}

//=============================================================================




