﻿//-----------------------------------------------------------------------------
// XNodeList
//
// Copyright 2005-2010 - Xcential Group LLC.
//
//-----------------------------------------------------------------------------

XNodeList.prototype = new XObject;
XNodeList.prototype.constructor = XNodeList;

//=============================================================================
// Constructor

function XNodeList(
   refOrItem,
   create
)
{
   refOrItem = (refOrItem == null) ? null : refOrItem;
   create = (create == null) ? true : create;

   if (create)
      return new XNodeList(refOrItem, false);

   //--------------------------------------------------------------------------
   // Private Interface

   //--------------------------------------------------------------------------
   // Privileged Interface

   this.valueOf = function()
   {

      return oNodeList;
   }

   //--------------------------------------------------------------------------

   this.setObjectValue = function(
      refOrItem
   )
   {
      refOrItem = (refOrItem == null) ? null : refOrItem;

      oNodeList = XNodeList.getNodeListFrom(refOrItem);

      return oNodeList;
   }

   //--------------------------------------------------------------------------
   // Initialization

   var oNodeList = this.setObjectValue(refOrItem);
   this.length = this.getLength();

}

XNodeList.prototype.objectClass = "XNodeList";

//=============================================================================
// Static Interface

XNodeList.getNodeListFrom = function(
   refOrItem
)
{
   refOrItem = (refOrItem == null) ? null : refOrItem;

   if (refOrItem == null)
      return null;

   var nodeList = null;
   var objectType = typeof(refOrItem);
   switch (objectType)
   {
      case "string":
         if (XRef.isRef(refOrItem))
         {
            try
            {
               var ref = refOrItem;
               var node = XNode.getNodeFrom(xml);
               nodeList = XNodeList.getNodeListFrom(node);
            }
            catch (error)
            {
               XApp.logEvent(XApp.EVENT_ERROR, error);
               throw XMsg("Cannot retrieve and parse item at '" + refOrItem + "' to a node list.", error);
            }
         }
         else if (XNode.isXML(refOrItem))
         {
            try
            {
               var xml = refOrItem;
               var node = XNode.getNodeFrom(xml);
               nodeList = XNodeList.getNodeListFrom(node);
            }
            catch (error)
            {
               XApp.logEvent(XApp.EVENT_ERROR, error);
               throw XMsg("Cannot parse item into a node list.", error);
            }
         }
         break;
      case "number":
         throw XMsg("Cannot create a node list from a number.");
         break;
      case "boolean":
         throw XMsg("Cannot create a node list from a boolean.");
         break;
      case "function":
         try
         {
            // Note: Safari returns the childNodes property of an element as a
            //       function rather an object. We look for the length property
            //       to detect that this has happened.
            if (refOrItem.length != null && refOrItem.length != undefined)
               nodeList = refOrItem;
            else
               nodeList = XNodeList.getNodeListFrom(refOrItem());
         }
         catch (error)
         {
            XApp.logEvent(XApp.EVENT_ERROR, error);
            throw XMsg("Cannot create a node list from a function.", error);
         }
         break;
      case "object":
         if (refOrItem.objectClass != null)
         {
            nodeList = XNodeList.getNodeListFrom(refOrItem.valueOf());
         }
         else
         {
            try
            {
               if (refOrItem.length != null && refOrItem.length != undefined)
                  nodeList = refOrItem;
               else if (refOrItem.nodeType == XNode.NODE_ELEMENT)
                  nodeList = refOrItem.childNodes;
            }
            catch (error)
            {
               XApp.logEvent(XApp.EVENT_ERROR, error);
               throw XMsg("Cannot create a node list from an object.", error);
            }
         }
         break;
      default:
         throw XMsg("Cannot create a node list from an unknown type.", error);
         break;
   }

   return nodeList;
}

//=============================================================================
// Public Interface

XNodeList.prototype.getLength = function()
{

   var nodeList = this.valueOf();

   return (nodeList) ? nodeList.length : 0;
}

//-----------------------------------------------------------------------------

XNodeList.prototype.getItem = function(
   index,
   castAs
)
{
   castAs = (castAs == null) ? XNode : castAs;

   var nodeList = this.valueOf();

   var item = (nodeList) ? nodeList.item(index) : null;

   try
   {
      return (item == null) ? null : castAs(item);
   }
   catch (error)
   {
      return null;
   }
}

XNodeList.prototype.X$ = XNodeList.prototype.getItem;

//=============================================================================

