﻿/****************************************************************************************************
* File: Base.js
* Author: Bryan Krasneski
*
* Description:
*		Base JavaScript client-side library for Trapeze.Framework
****************************************************************************************************/
Type.registerNamespace("Trapeze.Framework");

Trapeze.Framework.View = function(path, data, onSuccess, onFail)
{
  this._path = path;
  this._data = Sys.Serialization.JavaScriptSerializer.serialize(data);
  this._userSuccess = onSuccess;
  this._userFail = onFail;
  this._success_ = tie(this, this._success);
  this._fail_ = tie(this, this._fail);
}

Trapeze.Framework.View.prototype =
{
  invoke: function()
  {
    if (!this._path || this._path == "")
      throw "No view path specified";

    Trapeze.Framework.ViewService.RenderView(this._path, this._data, this._success_, this._fail_);
  },

  _success: function(response)
  {
    // Invoke user success function
    if (this._userSuccess) this._userSuccess(response);
  },

  _fail: function(response)
  {
    // Invoke user fail function
    if (this.userFail) this.userFail(response);
  }
}

// Un-namespaced helper functions

// Render a view into the element specified by dest
function renderView(path, data, dest, onSuccess, onFail)
{
  var elem = $(dest);

  var succ = function(response)
  {
    elem.update(response);
    if (onSuccess)
      onSuccess(response);
  };
  
  var view = new Trapeze.Framework.View(path, data, succ, onFail)
  view.invoke();

  return view;
}

// Invoke a view without updating an element
function invokeView(path, data, onSuccess, onFail)
{
  var view = new Trapeze.Framework.View(path, data, onSuccess, onFail)
  view.invoke();

  return view;
}

// Synonym for Function.createDelegate
// Ties the this context to the object for the invocation of the function f
function tie(obj, f)
{
  return Function.createDelegate(obj, f);
}

// BEK: This stuff used to be in Utility.js
// Some of this code should definitely be reworked

// ViewportLocation enumeration
var ViewportPosition = function() { };

ViewportPosition.prototype =
{
  None: 0,
  TopLeft: 1,
  TopCenter: 2,
  TopRight: 3,
  CenterRight: 4,
  BottomRight: 5,
  BottomCenter: 6,
  BottomLeft: 7,
  CenterLeft: 8,
  Center: 9
}

ViewportPosition.registerEnum("ViewportPosition");

var Box = Class.create(
{
  initialize: function(left, top, width, height)
  {
    this.left = left;
    this.top = top;
    this.width = width;
    this.height = height;
    this.right = this.left + width;
    this.bottom = this.top + height;
  },

  left: 0,
  top: 0,
  width: 0,
  height: 0,
  right: 0,
  bottom: 0
});

Element.addMethods(
{
  getBox: function(element)
  {
    var element = $(element);
    var dimensions = element.getDimensions();
    var offsets = element.cumulativeOffset();

    var box = new Box(offsets.left, offsets.top, dimensions.width, dimensions.height);
    return box;
  },

  setPosition: function(element, position)
  {
    var elem = $(element);
    var style = elem.style;

    // If no position specified, unposition
    if (!position)
    {
      style.left = "";
      style.top = "";

      return;
    }

    if (style.position != "absolute")
      style.position = "absolute";

    style.left = position.left + "px";
    style.top = position.top + "px";
  },

  setSize: function(el, size)
  {
    if (size.width)
      el.style.width = size.width + "px";

    if (size.height)
      el.style.height = size.height + "px";
  },

  setViewportPosition: function(element, position)
  {
    var element = $(element);
    var style = element.style;

    // If no position applied, remove positioning, return
    if (position == ViewportPosition.None)
    {
      return;
    }

    var vp = document.viewport.getBox();
    var e = element.getBox();

    // Calculate left/top offsets
    var l = 0;
    var t = 0;

    if (position == ViewportPosition.TopLeft)
    {
      l = vp.left;
      t = vp.top;
    }

    if (position == ViewportPosition.TopCenter)
    {
      l = vp.left + (vp.width / 2) - (e.width / 2);
      t = vp.top;
    }

    if (position == ViewportPosition.TopRight)
    {
      l = vp.left + vp.width - e.width;
      t = vp.top;
    }

    if (position == ViewportPosition.CenterRight)
    {
      l = vp.left + vp.width - e.width;
      t = vp.top + (vp.height / 2) - (e.height / 2);
    }

    if (position == ViewportPosition.BottomRight)
    {
      l = vp.left + vp.width - e.width;
      t = vp.top + vp.height - e.height;
    }

    if (position == ViewportPosition.BottomCenter)
    {
      l = vp.left + (vp.width / 2) - (e.width / 2);
      t = vp.top + vp.height - e.height;
    }

    if (position == ViewportPosition.BottomLeft)
    {
      l = vp.left;
      t = vp.top + vp.height - e.height;
    }

    if (position == ViewportPosition.CenterLeft)
    {
      l = vp.left;
      t = vp.top + (vp.height / 2) - (e.height / 2);
    }

    if (position == ViewportPosition.Center)
    {
      l = vp.left + (vp.width / 2) - (e.width / 2);
      t = vp.top + (vp.height / 2) - (e.height / 2);
    }

    // Clip left/top
    if (l < 0) l = 0;
    if (t < 0) t = 0;

    // Apply to style
    var box = new Box(l, t, 0, 0);
    element.setPosition(box);
  },

  cumulativeOffsetFrom: function(element, parent)
  {

    var valueT = 0, valueL = 0;
    parent = $(parent);
    element = $(element);

    do
    {
      valueT += element.offsetTop || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element && element != parent);
    return Element._returnOffset(valueL, valueT);
  },

  clear: function(elem)
  {
    elem.update("");
  }
});

Object.extend(document.viewport,
{
  getBox: function()
  {
    var dimensions = this.getDimensions();
    var offsets = this.getScrollOffsets();

    var box = new Box(offsets.left, offsets.top, dimensions.width, dimensions.height);
    return box;
  }
});

Object.extend(document,
{
  _getPageDimensions: function(w)
  {
    // var pageHeight = (document.height || document.body.offsetHeight);
    // var pageWidth = (document.width || document.body.offsetWidth);
    var pageWidth = 0;
    var pageHeight = 0;

    if (window.innerHeight && window.scrollMaxY) // Firefox 
    {
      pageWidth = window.innerWidth + window.scrollMaxX;
      pageHeight = window.innerHeight + window.scrollMaxY;
    }
    else if (document.body.scrollHeight > document.body.offsetHeight) // all but Explorer Mac
    {
      pageWidth = document.body.scrollWidth;
      pageHeight = document.body.scrollHeight;
    }
    else // works in Explorer 6 Strict, Mozilla (not FF) and Safari
    {
      pageWidth = document.body.offsetWidth + document.body.offsetLeft;
      pageHeight = document.body.offsetHeight + document.body.offsetTop;
    }

    return { width: pageWidth, height: pageHeight };
  },

  getBox: function()
  {
    var dimensions = this._getPageDimensions();
    var box = new Box(0, 0, dimensions.width, dimensions.height);
    return box;
  }
});

// Find an object by ID or die
function $OrDie(id)
{
  var elem = $(id);
  if (!elem)
    throw "Could not find element with id: " + id;

  return elem;
}

function radians(degrees)
{
  return degrees * (Math.PI / 180);
}
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();