var __aspxClientSchedulerSelectionHelper = null;
function SchedulerSelectionHelper_onmouseup(e) {
 if(__aspxClientSchedulerSelectionHelper != null) {
  __aspxClientSchedulerSelectionHelper.EndSelection(e);
  return true;
 }
}
function SchedulerSelectionHelper_onmousemove(e) {
 if(__aspxClientSchedulerSelectionHelper != null) {
  __aspxClientSchedulerSelectionHelper.MouseMove(e);
  return false;
 }
 return true;
}
function SchedulerSelectionHelper_onselectstart(e) {
 if(__aspxClientSchedulerSelectionHelper != null) {
  document.selection.empty();
  return false;
 }
 return true;
}
_aspxAttachEventToDocument("mouseup", SchedulerSelectionHelper_onmouseup);
_aspxAttachEventToDocument("mousemove", SchedulerSelectionHelper_onmousemove);
_aspxAttachEventToDocument("selectstart", SchedulerSelectionHelper_onselectstart);
ASPxSchedulerSelection = new _aspxCreateClass(null, {
 constructor: function(interval, resource, firstSelectedInterval) {
  this.interval = interval;
  this.resource = resource;
  this.firstSelectedInterval = _aspxIsExists(firstSelectedInterval) ? firstSelectedInterval : interval;
 }
});
ASPxClientSchedulerSelectionHelper = _aspxCreateClass(null, {
    constructor: function(scheduler, firstCell, continueSelection) {
    if(__aspxClientSchedulerSelectionHelper != null) __aspxClientSchedulerSelectionHelper.CancelSelection();
     this.scheduler = scheduler;
     if(!continueSelection || !_aspxIsExists(this.scheduler.selection)) {
      var resource = scheduler.GetCellResource(firstCell);
      var interval = scheduler.GetCellInterval(firstCell);
   this.scheduler.SetSelectionCore(new ASPxSchedulerSelection(interval, resource));
     }
     else
   this.ContinueSelection(firstCell);
     __aspxClientSchedulerSelectionHelper = this;
    },
    MouseMove: function(e) {
     var cell = this.scheduler.CalcHitTest(e).cell;
  if(_aspxIsExists(cell)) {
   this.ContinueSelection(cell);
  }  
    },
    ContinueSelection: function(cell) {
  var interval = this.scheduler.GetCellInterval(cell);
  if(!_aspxIsExists(interval))
   return;
  var newSelectionInterval = this.CalculateSelectionInterval(interval);
  if(!newSelectionInterval.Equals(this.scheduler.selection.interval)) {
   this.scheduler.SetSelectionInterval(newSelectionInterval);
  }
    },
    EndSelection: function(e) {
     this.CancelSelection();
    },
    CancelSelection: function(e) {
     __aspxClientSchedulerSelectionHelper = null;
 },
 CalculateSelectionInterval: function(hitInterval) {
  var firstInterval = this.scheduler.selection.firstSelectedInterval;
  if(firstInterval.IntersectsWith(hitInterval))
   return new ASPxClientTimeInterval(firstInterval.GetStart(), _aspxDateSubsWithTimezone(hitInterval.GetEnd(), firstInterval.GetStart()));
  if(hitInterval.GetStart() - firstInterval.GetEnd() >= 0)
   return new ASPxClientTimeInterval(firstInterval.GetStart(), _aspxDateSubsWithTimezone(hitInterval.GetEnd(), firstInterval.GetStart()));
  else
   return new ASPxClientTimeInterval(hitInterval.GetStart(), _aspxDateSubsWithTimezone(firstInterval.GetEnd(), hitInterval.GetStart()));
 }
});
ASPxAppointmentSelection = _aspxCreateClass(null, {
 constructor: function(scheduler) {  
  this.selectedAppointmentIds = new Array();
  this.selectedAppointmentViewInfos = new Array();
  this.scheduler = scheduler;
  this.lockCount = 0;
  this.deferredOnAppointmentSelection = false;
  this.internalSelection = false;
 },
 BeginUpdate: function(internalSelection) {
  this.internalSelection = internalSelection;
  this.lockCount++;
 },
 EndUpdate: function() {
  if(this.lockCount > 0) {
   this.lockCount--;
   if(this.lockCount == 0) {
    if(!this.internalSelection)
     this.ValidateViewInfos();
    if(this.deferredOnAppointmentSelection)
     this.OnAppointmentSelectionChanged();
    this.deferredOnAppointmentSelection = false;
   }
  }
 },
 ValidateViewInfos: function() {
  _aspxArrayClear(this.selectedAppointmentViewInfos);
  var count = this.selectedAppointmentIds.length;
  for(var i = count - 1; i >= 0; i--) {
   if(!this.AddAppointmentCore(this.selectedAppointmentIds[i]))
    _aspxArrayRemoveAt(this.selectedAppointmentIds, i);
  }
 },
 AddAppointmentCore: function(appointmentId)  {
  var viewInfos = this.scheduler.FindViewInfosByAppointmentId(appointmentId);
  var count = viewInfos.length;
  if(count <= 0)
   return false;
  for(var i = 0; i < count; i++)
     this.SelectAppointmentViewInfo(viewInfos[i]);
  return true;
 },   
 Prepare: function() {
  this.aptAdorner = this.scheduler.aptAdorner;
 },
 OnAppointmentSelectionChanged: function() {
  if(this.lockCount > 0)
   this.deferredOnAppointmentSelection = true;
  else
   this.scheduler.OnAppointmentSelectionChanged(this.selectedAppointmentIds);
 },
 AddAppointmentToSelection: function(appointmentId) {
  if(!this.scheduler.privateAllowAppointmentMultiSelect && this.selectedAppointmentIds.length >= 1)
   return;
  var contains = _aspxArrayIndexOf(this.selectedAppointmentIds, appointmentId) >= 0;
  if(contains)
   return;  
  if(this.lockCount > 0 && !this.internalSelection) {
   _aspxArrayPush(this.selectedAppointmentIds, appointmentId);
   this.OnAppointmentSelectionChanged();
  }
  else {
   if(this.AddAppointmentCore(appointmentId)) {
    _aspxArrayPush(this.selectedAppointmentIds, appointmentId);    
    this.OnAppointmentSelectionChanged();
   }
  }
 },
 ClearSelection: function() {
  var count = this.selectedAppointmentIds.length;
  if(count <= 0)
   return;
  _aspxArrayClear(this.selectedAppointmentIds);
  if(this.lockCount <= 0 || this.internalSelection) {
   count = this.selectedAppointmentViewInfos.length;
   for(var i = count - 1; i >= 0; i--)
    this.UnselectAppointmentViewInfoByIndex(i);
  }
  this.OnAppointmentSelectionChanged();
 },
 RemoveAppointmentFromSelection: function(appointmentId) {
  _aspxArrayRemove(this.selectedAppointmentIds, appointmentId);   
  if(this.lockCount <= 0) {
   var count = this.selectedAppointmentViewInfos.length;
   for(var i = count - 1; i >= 0; i--) {
    var viewInfo = this.selectedAppointmentViewInfos[i];
    if(viewInfo.appointmentId == appointmentId)
     this.UnselectAppointmentViewInfoByIndex(i);    
   }
  }
  this.OnAppointmentSelectionChanged();
 },
 ChangeAppointmentSelection: function(appointmentId) {
  var contains = _aspxArrayIndexOf(this.selectedAppointmentIds, appointmentId) >= 0;
  if(contains && this.selectedAppointmentIds.length > 1)
   this.RemoveAppointmentFromSelection(appointmentId);
  else
   if(this.scheduler.privateAllowAppointmentMultiSelect || this.selectedAppointmentIds.length < 1)
    this.AddAppointmentToSelection(appointmentId);
 },
 SelectSingleAppointment: function(appointmentId) {    
  if(this.selectedAppointmentIds.length == 1 && this.selectedAppointmentIds[0] == appointmentId)
   return;
  this.BeginUpdate(true);
  this.ClearSelection();
  this.AddAppointmentToSelection(appointmentId);
  this.EndUpdate();
 },
 IsAppointmentSelected: function(appointmentId) {
  return _aspxArrayIndexOf(this.selectedAppointmentIds, appointmentId) >= 0;  
 },
 UnselectAppointmentViewInfoByIndex: function(index) {
  var viewInfo = this.selectedAppointmentViewInfos[index];
  this.UnselectAppointmentViewInfoCore(viewInfo);
  _aspxArrayRemoveAt(this.selectedAppointmentViewInfos, index);    
 },
 UnselectAppointmentViewInfoCore: function(viewInfo) {
  viewInfo.contentDiv.style.zIndex = 1;
  var adornerDiv = viewInfo.adornerDiv;
  adornerDiv.oncontextmenu = null;
  adornerDiv.appointmentViewInfo = null;    
  _aspxRecycleNode(viewInfo.adornerDiv);
  viewInfo.adornerDiv = null;
 },
 SelectAppointmentViewInfo: function(viewInfo) {
  var adornerDiv = this.SelectAppointmentViewInfoCore(viewInfo);
  _aspxClearCurrentMouseEventDataObject();
  _aspxSubscribeSchedulerMouseEvents(adornerDiv, viewInfo);
  _aspxArrayPush(this.selectedAppointmentViewInfos, viewInfo);
 },
 SelectAppointmentViewInfoCore: function(viewInfo) {
  var adornerDiv = this.aptAdorner.cloneNode(true);
  adornerDiv.oncontextmenu = this.aptAdorner.oncontextmenu;
  var appointmentDiv = viewInfo.contentDiv;
  var parent = appointmentDiv.parentNode;  
  parent.appendChild(adornerDiv);
  adornerDiv.appointmentViewInfo = viewInfo;
  viewInfo.adornerDiv = adornerDiv;
  this.SetAdornerDivPosition(viewInfo);
  adornerDiv.style.zIndex = 2;
  appointmentDiv.style.zIndex = 3;
  return adornerDiv;
 },
 RecalcSelection: function() {
  var count = this.selectedAppointmentViewInfos.length;
  for(var i = 0; i < count; i++)
   this.SetAdornerDivPosition(this.selectedAppointmentViewInfos[i]);
 },
 SetAdornerDivPosition: function(viewInfo) {    
  var adornerDiv = viewInfo.adornerDiv;
  var appointmentDiv = viewInfo.contentDiv;
  _aspxSetSchedulerDivDisplay(adornerDiv, true);
  var borderWidth = Math.max(adornerDiv.offsetWidth - adornerDiv.clientWidth, 0) >> 1;
  var borderHeight = Math.max(adornerDiv.offsetHeight - adornerDiv.clientHeight, 0) >> 1;
  var offsetLeft = appointmentDiv.offsetLeft;
  var offsetTop = appointmentDiv.offsetTop;
  if(__aspxIE && __aspxBrowserMajorVersion >=8) {
   var offsetParent =  _aspxFindOffsetParent(appointmentDiv);
   offsetLeft = _aspxGetAbsolutePositionX(appointmentDiv) - _aspxGetAbsolutePositionX(offsetParent);
   offsetTop = _aspxGetAbsolutePositionY(appointmentDiv) - _aspxGetAbsolutePositionY(offsetParent);
  }
  adornerDiv.style.left = offsetLeft - borderWidth + "px";
  adornerDiv.style.top = offsetTop - borderHeight + "px";
  adornerDiv.style.width = appointmentDiv.offsetWidth + "px";  
  adornerDiv.style.height = appointmentDiv.offsetHeight + "px";
  adornerDiv.appointmentDiv = appointmentDiv;
  this.CalculateContentTableHeight(adornerDiv);  
 },
 CalculateContentTableHeight : function(adornerDiv) {    
  var children = adornerDiv.childNodes;  
  var count = children.length;
  for(var i = 0; i < count; i++) {
   var child = children[i];
   if(_aspxIsExists(child.tagName) && child.tagName.toUpperCase() == "TABLE") {
    child.style.height = adornerDiv.offsetHeight + "px";
    break;
   }
  }
 }
});
ASPxCellHighlightElement = _aspxCreateClass(null, {
 constructor: function(container, left, dxtop, width, height, interval) {
  this.left = left;
  this.top = dxtop;
  this.width = width;
  this.height = height;
  this.interval = interval;
  this.container = container;
 }
});
ASPxCellHighlightViewInfo = _aspxCreateClass(null, {
 constructor: function(scheduler, viewInfo, divTemplate, layer) {
  this.scheduler = scheduler;
  this.viewInfo = viewInfo;
  this.parent = viewInfo.parent;
  this.divTemplate = divTemplate;
  this.highlightDivs = new Array();
  this.highlightElements = new Array();
  this.highlightDivCache = new Array();
  this.layer = layer;
 }, 
 HighlightCells: function(interval, resource, smartTagDiv, highlightPartiallySelectedCell, selectionVisible) {
  if(!_aspxIsExists(interval) || !_aspxIsExists(resource))
   return;   
  this.RemovePrevCellHighlight();
  if(selectionVisible) {
   this.CreateHighlightElements(interval, resource, highlightPartiallySelectedCell);
   this.CreateHighlightDivs(smartTagDiv);
  }
 },
 RemovePrevCellHighlight: function() {
  var count = this.highlightDivs.length;   
  for(var i = 0; i < count; i++) {   
   this.ReleaseHighlightDiv(this.highlightDivs[i]);
  }
    _aspxArrayClear(this.highlightDivs);
    _aspxArrayClear(this.highlightElements);
 },
 CreateHighlightElements: function(interval, resource, highlightPartiallySelectedCell) {
  var cellContainers = this.viewInfo.cellContainers;
  var count = cellContainers.length;
  var viewInfo = this.viewInfo;
  for(var i = 0; i < count; i++) {
   var container = cellContainers[i];
   if(container.resource != resource || !container.interval.IntersectsWithExcludingBounds(interval))
    continue;
   if(interval.Contains(container.interval)) {
    this.HighlightContainer(container);
    continue;
   }
   var cellCount = container.cellCount;
   for(var j = 0; j < cellCount; j++) {
    var cell = this.viewInfo.GetCell(i, j);
    if( _aspxIsExists(cell)) {
     var cellInterval = this.scheduler.GetCellInterval(cell);          
     var highlightCell;
     if(highlightPartiallySelectedCell)
      highlightCell = cellInterval.IntersectsWithExcludingBounds(interval);
     else
      highlightCell = interval.Contains(cellInterval);
     if(highlightCell)
      this.HighlightCell(cell);
    }
   }
  }
 },
 CreateHighlightDivs: function(smartTagDiv) {
  var count = this.highlightElements.length;
  for(var i = 0; i < count; i++) {
   var element = this.highlightElements[i];
   var highlightDiv = this.CreateHighlightDiv(element);
   if(_aspxIsExists(smartTagDiv)) {
    _aspxSubscribeSchedulerMouseEvents(highlightDiv, highlightDiv);
    highlightDiv.mouseEvents = new ASPxSchedulerMouseEvents();
    _aspxAddSmartTag(highlightDiv, smartTagDiv);
   }
   _aspxArrayPush(this.highlightDivs, highlightDiv);
  }
 },
 CreateHighlightDiv: function(highlightElement) {
  var highlightDiv = this.CreateHightlightDiv();
  highlightDiv.style.height = "0px";
  highlightDiv.container = highlightElement.container;
  highlightDiv.style.left = highlightElement.left + "px";
  highlightDiv.style.top = highlightElement.top + "px";
  highlightDiv.style.width = highlightElement.width + "px";
  highlightDiv.style.height = highlightElement.height + "px";
  _aspxSetElementDisplay(highlightDiv, true);
  return highlightDiv;
 },
 CreateHightlightDiv: function() {
  if(this.highlightDivCache.length > 0)
   return this.highlightDivCache.pop();
  else {
   var highlightDiv = this.divTemplate.cloneNode(true);
   highlightDiv.oncontextmenu = highlightDiv;
   _aspxSetElementDisplay(highlightDiv, false);
   this.viewInfo.parent.AppendChildToLayer(highlightDiv, this.layer);
   return highlightDiv;
  }
 },
 ReleaseHighlightDiv: function(div) {  
  _aspxArrayPush(this.highlightDivCache, div);
  _aspxSetElementDisplay(div, false);
 },
 HighlightContainer: function(container) {
  if(!this.IsValidContainer(container))
   return;
  var bounds = this.parent.CalcRelativeContainerBounds(this.viewInfo, container);
  if(!_aspxIsExists(bounds))
   return;
  var left = bounds.left;
  var dxtop = bounds.top;
  var width = bounds.width;
  var height = bounds.height;
  var newHighlightElement = new ASPxCellHighlightElement(container, left, dxtop, width, height, container.interval);
  _aspxArrayPush(this.highlightElements, newHighlightElement);
 },
 HighlightCell: function(cell) {
  var findResult = this.FindAdjacentHighlightElement(cell);
  if(_aspxIsExists(findResult)) {
   var highlightElement = findResult.highlightElement;
   if(_aspxIsExists(findResult.newLeft))
    highlightElement.left = findResult.newLeft;
   if(_aspxIsExists(findResult.newTop))
    highlightElement.top = findResult.newTop;
   if(_aspxIsExists(findResult.newRight))
    highlightElement.width = findResult.newRight - highlightElement.left;
   if(_aspxIsExists(findResult.newBottom))
    highlightElement.height = findResult.newBottom - highlightElement.top;
   if(_aspxIsExists(findResult.newStartTime))
    highlightElement.interval.SetStart(findResult.newStartTime);
   if(_aspxIsExists(findResult.newEndTime))
    highlightElement.interval.SetEnd(findResult.newEndTime);
  }
  else {
   var container = this.scheduler.GetCellContainer(cell);
   if(!this.IsValidContainer(container))
    return;
   var left = this.parent.CalcRelativeElementLeft(cell);
   var dxtop = this.parent.CalcRelativeElementTop(cell);
   var width = cell.offsetWidth;
   var height = this.parent.CalcCellHeight(cell);
   var startTime = this.scheduler.GetCellStartTime(cell);
   var endTime = this.scheduler.GetCellEndTime(cell);
   if(!_aspxIsExists(container) || !_aspxIsExists(left) || !_aspxIsExists(dxtop) || !_aspxIsExists(width) || !_aspxIsExists(height) || !_aspxIsExists(startTime) || !_aspxIsExists(endTime))
    return;
   var interval = new ASPxClientTimeInterval(startTime, _aspxDateSubsWithTimezone(endTime, startTime));
   var newHighlightElement = new ASPxCellHighlightElement(container, left, dxtop, width, height, interval);
   _aspxArrayPush(this.highlightElements, newHighlightElement);
  }
 },
 FindAdjacentHighlightElement: function(cell) {
  var count = this.highlightElements.length;
  var startTime = this.scheduler.GetCellStartTime(cell);
  var endTime = this.scheduler.GetCellEndTime(cell);  
  var container = this.scheduler.GetCellContainer(cell);
  if (!_aspxIsExists(startTime) || !_aspxIsExists(endTime) || !_aspxIsExists(container))
   return null;
  for (var i = 0; i < count; i++) {
   var highlightElement = this.highlightElements[i];
   if (highlightElement.container != container)
    continue;
   var highlightInterval = highlightElement.interval;
   var cellBeforeHighlight = (highlightInterval.GetStart() - endTime) == 0;
   var cellAfterHighlight = (highlightInterval.GetEnd() - startTime) == 0;
   if (!cellBeforeHighlight && !cellAfterHighlight)
    continue;
   var result = new Object();
   if (cellBeforeHighlight)
    result.newStartTime = startTime;
   if (cellAfterHighlight)
    result.newEndTime = endTime;
   if(this.IsVisuallyAdjacent(highlightElement, cell, result)) {
    result.highlightElement = highlightElement;
    return result;    
   }
  }
  return null;
 } 
});
ASPxHorizontalCellHighlightViewInfo = _aspxCreateClass(ASPxCellHighlightViewInfo, {
 constructor: function(scheduler, viewInfo, divTemplate, layer) {
  this.constructor.prototype.constructor.call(this, scheduler, viewInfo, divTemplate, layer);
 },
 IsValidContainer: function(container) {
  return _aspxIsExists(container.isVertical) && (!container.isVertical);
 },
 IsVisuallyAdjacent: function(highlightElement, cell, result) {
  var cellTop = this.parent.CalcRelativeElementTop(cell);
  var cellHeight = this.parent.CalcCellHeight(cell);
  if(cellTop == highlightElement.top && cellHeight == highlightElement.height) {
   var cellLeft = this.parent.CalcRelativeElementLeft(cell);
   result.newLeft = Math.min(cellLeft, highlightElement.left);
   result.newRight = Math.max(this.parent.CalcRelativeElementRight(cell), highlightElement.left + highlightElement.width);    
   return true;
  }
 }
});
ASPxVerticalCellHighlightViewInfo = _aspxCreateClass(ASPxCellHighlightViewInfo, {
 constructor: function(scheduler, viewInfo, divTemplate, layer) {
  this.constructor.prototype.constructor.call(this, scheduler, viewInfo, divTemplate, layer);
 },
 IsValidContainer: function(container) {
  return _aspxIsExists(container.isVertical) && container.isVertical;
 },
 IsVisuallyAdjacent: function(highlightElement, cell, result) {
  var cellLeft = this.parent.CalcRelativeElementLeft(cell);
  if(cellLeft == highlightElement.left && cell.offsetWidth == highlightElement.width) {
   var cellTop = this.parent.CalcRelativeElementTop(cell);
   result.newTop = Math.min(cellTop, highlightElement.top);
   result.newBottom = Math.max(this.parent.CalcRelativeElementBottom(cell), highlightElement.top + highlightElement.height);    
   return true;
  }
 } 
});

