﻿//-----------------------------------------------------------------------------
// XCalDoc
//
// Copyright 2005-2010 - Xcential Group LLC.
//
//-----------------------------------------------------------------------------

XCalDoc.prototype = new XDoc;
XCalDoc.prototype.constructor = XCalDoc;

//=============================================================================
// Constructor

function XCalDoc(
   refOrItem,
   create
)
{
   refOrItem = (refOrItem == null) ? null : refOrItem;
   create = (create == null) ? true : false;

   if (create)
      return new XCalDoc(refOrItem, false);

   //--------------------------------------------------------------------------
   // Private Interface

   //--------------------------------------------------------------------------
   // Privileged Interface

   this.valueOf = function()
   {

      return oDoc;
   }

   //--------------------------------------------------------------------------

   this.setObjectValue = function(
      refOrItem
   )
   {
      refOrItem = (refOrItem == null) ? null : refOrItem;

      oDoc = XDoc.getDocFrom(refOrItem);

      return oDoc;
   }

   //--------------------------------------------------------------------------
   // Initialization

   var oDoc = this.setObjectValue(refOrItem);

   this.ref = (refOrItem && typeof(refOrItem) == "string") ? refOrItem : null;

}

XCalDoc.prototype.objectClass = "XCalDoc";

//=============================================================================
// Static Interface

XCalDoc.NAMESPACE_URI = "http://www.xcential.com/schemas/2007/xcal";

//=============================================================================
// Public Interface

XCalDoc.prototype.getURL = function(
   castAs
)
{
   castAs = (castAs == null) ? null : castAs;

   var doc = (this.filter && this.filter.originalDoc) ? this.filter.originalDoc : this.valueOf();

   var url = (XString(this.ref).isSomething()) ? XRef(this.ref).getURL() : doc.url;

   return (castAs == null) ? url : castAs(url);
}

//-----------------------------------------------------------------------------

XCalDoc.prototype.getEvent = function(
   id
)
{

   var event = this.X$("//xcal:Event[@id='" + id + "']");

   return (event) ? XCalEvent(event) : null;
}

//-----------------------------------------------------------------------------

XCalDoc.prototype.addEvent = function(
   id,
   startsAt,
   endsAtOrDuration,
   className,
   transp,
   status,
   priority,
   before
)
{
   id = (id == null) ? XUtils.generateId("urn:xcential-com:caldoc:", XUtils.SCHEME_GUID) : id;
   endsAtOrDuration = (endsAtOrDuration == null) ? null : endsAtOrDuration;
   className = (className == null) ? XCalEvent.CLASS_PUBLIC : className;
   transp = (transp == null) ? XCalEvent.TRANSP_OPAQUE : transp;
   status = (status == null) ? XCalEvent.STATUS_TENTATIVE : status;
   priority = (priority == null) ? 0 : priority; // 0 = Undefined, 1 = highest, 9 = lowest
   before = (before == null) ? null : before;

   var endsAt = (endsAtOrDuration && !(/^P/i).test(endsAtOrDuration)) ? endsAtOrDuration : null;
   var duration = (endsAtOrDuration && (/^P/i).test(endsAtOrDuration)) ? endsAtOrDuration : null;

   var doc = this.valueOf();

   if (!before)
   {
      var startsAtXDate = XDate(startsAt);
      var events = this.X$$("//xcal:Event");
      for (var i=0; i<events.length; i++)
      {
         var event = events.X$(i, XCalEvent);
         var eventXDate = event.getStartsAt(XDate);
         if (startsAtXDate.isSameDay(eventXDate) && startsAtXDate.getHours() == 0)
         {
            continue; // Try and put events without a time at the end
         }
         if (startsAtXDate.isSameDay(eventXDate) && eventXDate.getHours() == 0)
         {
            before = event; // Try and put events without a time at the end
            break;
         }
         if (startsAtXDate.isBefore(eventXDate))
         {
            before = event;
            break;
         }
      }
   }

   var xEvent = this.createNode(XNode.NODE_ELEMENT, "Event", XCalDoc.NAMESPACE_URI, XCalEvent);
   this.getRoot().getChild("events").addChild(xEvent, before);
   xEvent.init(id, null, startsAt, endsAt, duration, className, transp, status, priority);

   return xEvent;
}

//-----------------------------------------------------------------------------

XCalDoc.prototype.getFilter = function()
{

   return this.filter;
}

//-----------------------------------------------------------------------------

XCalDoc.prototype.clearFilter = function()
{

   this.setFilter();

}

//-----------------------------------------------------------------------------

XCalDoc.prototype.setFilter = function(
   categories
)
{
   categories = (categories == null) ? [] : categories;

   if (this.filter && this.filter.originalDoc)
   {
      this.setObjectValue(this.filter.originalDoc);
      this.filter = null;
   }

   var doc = this.valueOf();

   if (categories.length > 0)
   {
      var filterXPath = "//xcal:Event[";
      for (var i=0; i<categories.length; i++)
      {
         var category = categories[i];
         filterXPath += ((i>0) ? " or " : "") + "./xcal:category=\"" + category + "\"";
      }
      filterXPath += "]";

      var id = this.getRoot().getAttribute("id");

      var filteredXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
      filteredXML += "<Calendar xmlns=\"http://www.xcential.com/schemas/2007/xcal\" " +
         ((XString(id).isSomething()) ? "id=\"" + id + "\" " : "") +
      ">\n";

      var events = this.X$$(filterXPath);
      for (var i=0; i<events.length; i++)
      {
         var eventXNode = events.X$(i);
         filteredXML += "   " + eventXNode.toXML() + "\n";
      }
      filteredXML += "</Calendar>\n";

      this.filter = new Array();
      this.filter.categories = categories;
      this.filter.filterXPath = filterXPath;
      this.filter.originalDoc = doc;

      this.setObjectValue(filteredXML);
   }

}

//=============================================================================


