//Function to create silverlight scrollbar object
function createSilverlight_HtmlScrollbar(divSilverlightContainerID, divHtmlContentID)
{
    // Add scrollbar to HTML content
  Silverlight.createObjectEx(
    {
      source: "Scrollbar.xaml",
      parentElement: document.getElementById(divSilverlightContainerID),
      id: divSilverlightContainerID + "_scrollbar",
      properties: { width: "100%", height: "100%", version: "1.0", isWindowless: "true", background:'transparent' },
      events: { onLoad: onLoad_HtmlScrollbar, onError: function(sender, args) {
				var errorDiv = document.getElementById("errorLocation");
				if (errorDiv != null) {
					var errorText = args.errorType + "- " + args.errorMessage;
							
					if (args.ErrorType == "ParserError") {
						errorText += "<br>File: " + args.xamlFile;
						errorText += ", line " + args.lineNumber;
						errorText += " character " + args.charPosition;
					}
					else if (args.ErrorType == "RuntimeError") {
						errorText += "<br>line " + args.lineNumber;
						errorText += " character " +  args.charPosition;
					}
					errorDiv.innerHTML = errorText;
				}	
			} },
      initParams: divHtmlContentID
    }
  );
}
//Function that fires after scrollbar loads.
function onLoad_HtmlScrollbar(control, userContext, rootElement)
{
    // Add scrollbar to silverlight content.
    var plugin = rootElement.getHost();
    var divHtmlContent = document.getElementById(plugin.initParams);
    var scrollbar = new ScrollingCanvasForHTML(rootElement, divHtmlContent);
    rootElement.Children.RemoveAt(0);
    
    rootElement.Children.Add(scrollbar.canvas);
    scrollbar.resize(divHtmlContent.offsetHeight);
}

// Constructor for ScrollingCanvasForHTML
function ScrollingCanvasForHTML(rootElement, divHtmlContent)
{
  // Used for scrollbar Width, upArrow/downArrow Width and Height, and the
  // delta for position and time when perfoming continuous scrolling:
  this.SMALLVALUE = 16;
  
  // Create the elements and add the passed-in content as a child of the root
  //this.canvas = rootElement.GetHost().CreateFromXaml(xaml, true);  //content.GetHost().Content.CreateFromXaml(xaml, true);
  //this.canvas.Children.Add(content);
  this.canvas = rootElement.Children.GetItem(0);
  this.divHtmlContent = divHtmlContent;
    
  // Store the important elements in member variables
  this.clip = this.canvas.FindName("clip");
  this.scrollBar = this.canvas.FindName("scrollBar");
  this.upArrow = this.canvas.FindName("upArrow");
  this.downArrow = this.canvas.FindName("downArrow");
  this.thumb = this.canvas.FindName("thumb");
  this.scrollBg = this.canvas.FindName("scrollbar_bg");
  //this.thumbBody = this.canvas.FindName("thumbBody");
  //this.thumbCircle = this.canvas.FindName("thumbCircle");
  //this.content = content;

  // Move any Canvas.Left and Canvas.Top setting from the content
//  this.canvas["Canvas.Left"] = content["Canvas.Left"];
//  this.canvas["Canvas.Top"] = content["Canvas.Top"];
//  content["Canvas.Left"] = 0;
//  content["Canvas.Top"] = 0;

  // Attach event handlers to the thumb
  this.thumb.AddEventListener("MouseLeftButtonDown",
    delegate(this, this.onThumbMouseLeftButtonDown));
  this.thumb.AddEventListener("MouseMove", delegate(this, this.onThumbMouseMove));
  this.thumb.AddEventListener("MouseLeftButtonUp",
    delegate(this, this.onThumbMouseLeftButtonUp));

  // Attach event handlers to the up and down arrows
  this.upArrow.AddEventListener("MouseLeftButtonDown",
    delegate(this, this.onArrowMouseLeftButtonDown));
  this.upArrow.AddEventListener("MouseLeftButtonUp",
    delegate(this, this.onArrowMouseUpOrLeave));
  this.upArrow.AddEventListener("MouseLeave",
    delegate(this, this.onArrowMouseUpOrLeave));
  this.downArrow.AddEventListener("MouseLeftButtonDown",
    delegate(this, this.onArrowMouseLeftButtonDown));
  this.downArrow.AddEventListener("MouseLeftButtonUp",
    delegate(this, this.onArrowMouseUpOrLeave));
  this.downArrow.AddEventListener("MouseLeave",
    delegate(this, this.onArrowMouseUpOrLeave));

  // By default, set the root Canvas height to match
  // the content height (which means no scrolling)
  //this.resize(content.Width, content.Height);
  
  this.resize(divHtmlContent.offsetHeight);
}

//Function to resize to the content's width and desired height
ScrollingCanvasForHTML.prototype.resize = function(height)
{
    recordDebugMessage('height: ' + height, 1);
  // Resize the canvas and its clipping rectangle
  // (leaving room for the scrollbar)
  //this.canvas.Width = this.content.Width + this.SMALLVALUE;
  //this.canvas.Height = height;
  this.canvas.Height = height;
  var agContainerDiv = document.getElementById(this.canvas.getHost().id);
  agContainerDiv.style.height = height + 'px';  
  
  this.canvas.Width = (this.divHtmlContent.clientWidth - 47);
  agContainerDiv.style.width = this.canvas.Width + 'px';
  
  this.scrollBar["Canvas.Left"] = this.canvas.Width - this.SMALLVALUE;
  
  // right-align scrollbar
  //this.canvas.FindName("scrollBar")["Canvas.Left"] = this.canvas.Width - this.SMALLVALUE;
  
  
  
  //this.clip.Rect = "0,0," + this.canvas.Width + "," + this.canvas.Height;

////  // Don't show the scrollbar if the content isn't taller than the canvas
////  //if (this.content.Height <= height)
////  if (this.divHtmlContent.offsetHeight <= height)
////  {
////    this.scrollBar.Visibility = "Collapsed";
////    return;
////  }
  
  // Show, position and resize the scrollbar
  this.scrollBar.Visibility = "Visible";
  //this.scrollBar["Canvas.Left"] = this.content.Width;
  
  this.scrollBar.Height = height;
  this.scrollBg.Height = height - this.SMALLVALUE;
  recordDebugMessage('scrollBar: ' + this.scrollBar.Height, 1);
  this.downArrow["Canvas.Top"] = height - this.SMALLVALUE;
  this.thumb.Height = Math.max(this.SMALLVALUE,
    (height - 2 * this.SMALLVALUE) * height / this.divHtmlContent.scrollHeight);
   
//  this.thumbCircle["Canvas.Top"] = this.thumb.Height / 2
//                                 - this.thumbCircle.Height / 2;
//  this.maxThumbPosition = this.canvas.Height - this.SMALLVALUE
//                        - this.thumb.Height;
    this.maxThumbPosition = this.canvas.Height - this.SMALLVALUE
                        - this.thumb.Height;

  // Calculate the ratio of content scrolling distance to thumb scrolling distance
//  this.ratio = (this.divHtmlContent.offsetHeight - height) /
//               (height - 2 * this.SMALLVALUE - this.thumb.Height);
    this.ratio = this.divHtmlContent.scrollHeight / (height - 2 * this.SMALLVALUE - this.thumb.Height);
    recordDebugMessage('ratio: ' + this.ratio, 1);
    var padHtml = this.divHtmlContent.style.paddingTop;
    if (padHtml)
        padHtml = parseInt(padHtml) + (this.SMALLVALUE * this.ratio);
    else
        padHtml = (this.ratio / this.SMALLVALUE);
    //this.divHtmlContent.style.paddingTop = padHtml + 'px';
    //this.divHtmlContent.style.height = (parseInt(this.divHtmlContent.scrollHeight) - 2 * parseInt(padHtml)) + 'px';

  // Reset the scrollbar
  this.scrollTo(0);
};

//Function to capture the mouse when pressing the thumb
ScrollingCanvasForHTML.prototype.onThumbMouseLeftButtonDown =
function(sender, mouseEventArgs)
{
  this.thumb.CaptureMouse();
  this.lastThumbPoint = mouseEventArgs.GetPosition(null);
  this.thumbDragging = true;
};

//Function to move the thumb along with the mouse
ScrollingCanvasForHTML.prototype.onThumbMouseMove = function(sender, mouseEventArgs)
{
  if (this.thumbDragging)
  {
    var point = mouseEventArgs.GetPosition(null);
    this.scrollTo(this.thumb["Canvas.Top"] + point.Y - this.lastThumbPoint.Y);
    this.lastThumbPoint = point;
  }
};

//Function to release mouse capture when releasing the thumb
ScrollingCanvasForHTML.prototype.onThumbMouseLeftButtonUp =
function(sender, mouseEventArgs)
{
  this.thumb.ReleaseMouseCapture();
  this.thumbDragging = false;
};

//Function to move the content and thumb to the specified vertical position
ScrollingCanvasForHTML.prototype.scrollTo = function(thumbPosition)
{

  // Constrain the position to the bounds of the scrollbar
  thumbPosition = Math.max(thumbPosition, this.SMALLVALUE);
  thumbPosition = Math.min(thumbPosition, this.maxThumbPosition);

  if (this.thumb["Canvas.Top"] == thumbPosition)
  {
    // We're already at the desired position.
    // Just in case this is from a continuous scroll:
    this.stopContinuousScrolling();
  }
  else
  {
    // Move the thumb to the desired position
    this.thumb["Canvas.Top"] = thumbPosition;

    // Move the content to the corresponding position
    //this.content["Canvas.Top"] = (this.SMALLVALUE - thumbPosition) * this.ratio;
    //this.divHtmlContent.scrollTop = (this.SMALLVALUE - thumbPosition) * this.ratio;
    
    this.divHtmlContent.scrollTop = (thumbPosition - this.SMALLVALUE) * this.ratio;
    
    recordDebugMessage('thumb: ' + thumbPosition, 1);
    recordDebugMessage('scrollTop: ' + this.divHtmlContent.scrollTop, 1);
    //alert(this.divHtmlContent.scrollTop);
  }
};

//Function to scroll continuously when pressing the up or down arrow
ScrollingCanvasForHTML.prototype.onArrowMouseLeftButtonDown =
function(sender, mouseEventArgs)
{
  this.startContinuousScrolling(sender.Name == "upArrow");
};

//Function to stop scrolling continuously when releasing the up or down arrow
ScrollingCanvasForHTML.prototype.onArrowMouseUpOrLeave = function(sender, mouseEventArgs)
{
  this.stopContinuousScrolling();
};

//Function to begin continuous scrolling
ScrollingCanvasForHTML.prototype.startContinuousScrolling = function(up)
{
  var delta = this.SMALLVALUE;
  if (up)
    delta *= -1;

  // Call scroll every couple of milliseconds, adding the delta
  var scrollTo = delegate(this, this.scrollTo);
  var thumb = this.thumb;
  var callback = function() { scrollTo(thumb["Canvas.Top"] + delta); }
  this.handle = setInterval(callback, this.SMALLVALUE);
};

//Function to end the continuous scrolling, if it is happening
ScrollingCanvasForHTML.prototype.stopContinuousScrolling = function()
{
  clearInterval(this.handle);
};

//// Helper for attaching events to instance functions
//function delegate(target, callback) {
//  return function() { callback.apply(target, arguments); };
//}
function getPageCoords(el) 
{ 
  var coords = {x: 0, y: 0};
  do {
    coords.x += el.offsetLeft;
    coords.y += el.offsetTop;
  }
  while ((el = el.offsetParent));
  return coords;
}
