function PaneControl(id, cssContent)
{
  var _id = id;
  var _parent = null;
  var CSS_CLASS_PANE = "window";
  var CSS_CLASS_CORNER = "corner";
  var CSS_CLASS_ROW = "row";
  var CSS_CLASS_COLUMN = "bar";
  var CSS_CLASS_CONTENT = "fill";

  var pane = $(document.createElement('div'));
  var topDiv = $(document.createElement('div'));
  var topDivLeft = $(document.createElement('div'));
  var topDivRight = $(document.createElement('div'));
  var topDivMiddle = $(document.createElement('div'));
  var midDiv = $(document.createElement('div'));
  var midDivLeft = $(document.createElement('div'));
  var midDivRight = $(document.createElement('div'));
  var midDivMiddle = $(document.createElement('div'));
  var bottomDiv = $(document.createElement('div'));
  var bottomDivLeft = $(document.createElement('div'));
  var bottomDivRight = $(document.createElement('div'));
  var bottomDivMiddle = $(document.createElement('div'));

  pane.attr('id', _id);
  pane.addClass(CSS_CLASS_PANE);
  topDiv.attr('id', _id + 'Top');
  topDiv.addClass(CSS_CLASS_ROW);
  topDiv.addClass('top');
  topDivLeft.addClass(CSS_CLASS_CORNER);
  topDivLeft.addClass('left');
  topDivRight.addClass(CSS_CLASS_CORNER);
  topDivRight.addClass('right');
  topDivMiddle.addClass('middle');

  midDiv.attr('id', _id + 'Middle');
  midDiv.addClass(cssContent);
  midDivLeft.addClass(CSS_CLASS_COLUMN);
  midDivLeft.addClass('left');
  midDivLeft.addClass(cssContent);
  midDivRight.addClass(CSS_CLASS_COLUMN);
  midDivRight.addClass('right');
  midDivRight.addClass(cssContent);
  midDivMiddle.addClass(cssContent);
  midDivMiddle.addClass(CSS_CLASS_CONTENT);

  bottomDiv.attr('id', _id + 'Bottom');
  bottomDiv.addClass(CSS_CLASS_ROW);
  bottomDiv.addClass('bottom');
  bottomDivLeft.addClass(CSS_CLASS_CORNER);
  bottomDivLeft.addClass('left');
  bottomDivRight.addClass(CSS_CLASS_CORNER);
  bottomDivRight.addClass('right');
  bottomDivMiddle.addClass('middle');

  topDiv.append(topDivLeft);
  topDiv.append(topDivRight);
  topDiv.append(topDivMiddle);

  midDiv.append(midDivLeft);
  midDiv.append(midDivRight);
  midDiv.append(midDivMiddle);

  bottomDiv.append(bottomDivLeft);
  bottomDiv.append(bottomDivRight);
  bottomDiv.append(bottomDivMiddle);

  pane.append(topDiv);
  pane.append(midDiv);
  pane.append(bottomDiv);

  this.appendChild = function(child)
  {
    midDivMiddle.append(child);
  }

  this.expand = function(e)
  {
    var displayHeight = $(window).height();
    var actualHeight = midDiv.outerHeight();

    var targetHeight = displayHeight - midDiv.position().top - bottomDiv.outerHeight(true);
    if (targetHeight != actualHeight)
    {
      midDiv.children().height(targetHeight);
    }
  }

  this.getNode = function() { return pane[0]; }
  this.getContentNode = function() { return midDivMiddle[0]; }
}

function TabControl(id, tabData, selectedIndex)
{
  var _onTabChanged = null;
  var CSS_CLASS_TAB = "tab";
  var CSS_CLASS_LINK = "select";
  var CSS_CLASS_ACTIVE = "active";
  var _id = id;
  var _parent = null;

  var _element = $(document.createElement("div"));
  _element.attr("id", _id);
  _element.data("SelectedIndex", selectedIndex);

  var _selectTab = function(args, index)
  {
    var parentTab = null;
    var clickedIndex = 0;

    if (args)
    {
      clickedIndex =  $(this).data("Index");
      parentTab = $(this).parent();
    }
    else
    {
      clickedIndex = index;
      parentTab = _element.children().eq(index);
    }
    var selectedIndex = _element.data("SelectedIndex");
    _element.data("SelectedIndex", clickedIndex);

    parentTab.siblings("." + CSS_CLASS_ACTIVE).removeClass(CSS_CLASS_ACTIVE);
    parentTab.addClass(CSS_CLASS_ACTIVE);

    if (_onTabChanged != null && selectedIndex != clickedIndex)
    {
      _onTabChanged(null, $(this).data("Argument"));
    }
  }

  for (var i=0; i<tabData.length; i++)
  {
    var tab = $(document.createElement("span"));
    var link = $(document.createElement("a"));
    tab.attr("id", CSS_CLASS_TAB + tabData[i].name);
    tab.addClass(CSS_CLASS_TAB);
    if (_element.data("SelectedIndex") == i)
    {
      tab.addClass(CSS_CLASS_ACTIVE);
    }
    link.attr("id", CSS_CLASS_LINK + tabData[i].name);
    link.addClass(tabData[i].css);
    link.attr("title", tabData[i].title);
    link.data("Argument", tabData[i].argument);
    link.data("Index", i);
    link.bind("click", _selectTab);
    tab.append(link);
    _element.append(tab);
  }

  this.getNode = function() { return _element[0]; }
  this.activeTabIndex = function(index)
  {
    if (index == undefined) { return _element.data("SelectedIndex"); }
    else { _selectTab(null, index); }
  }
  this.onTabChanged = function (callback) { _onTabChanged = callback; }
}

function ContainerControl(id)
{
  var _id = id;
  var _parent = null;
  var _element = $(document.createElement("div"));
  _element.attr("id", _id);

  this.appendChild = function(child)
  {
    _element.append(child);
  }

  this.getNode = function() { return _element; }
}

function ResizeControl(id, min, max)
{
  var _id = id;
  var _min = 213;
  var _max = 568;
  var _parent = null;
  var _resizing = false;
  var _element = $(document.createElement("div"));
  var _dragElement = $(document.createElement("div"));
  _element.attr("id", _id);
  _element.addClass("resize");

  var resizeCallback = function(e)
    {
      var dragPosition = e.pageX - 2;
      var windowWidth = $(window).width();
      var maxLeft = windowWidth - _min;
      var minLeft = windowWidth - _max;
      if (dragPosition < minLeft) { dragPosition = minLeft; }
      else if (dragPosition > maxLeft) { dragPosition = maxLeft; }
      _dragElement.css("left", dragPosition.toString() + "px");
    };

  var resizeEndCallback = function(e)
    {
      var windowWidth = $(window).width();
      var width = windowWidth - e.pageX - 5;

      if (width < _min - 7) { width = _min - 7; }
      else if (width > _max - 7) { width = _max - 7; }

      $("#reader").css("margin-right", width.toString() + "px");
      $("#tools").css("width", (width+9).toString() + "px");
      _dragElement.css("display", "none");
      $(document).unbind("mousemove", resizeCallback);
      $(document).unbind("mouseup", resizeEndCallback);
    };

  _element.bind("selectstart", function(e) { return false; } );
  _element.bind("mousedown", function(e)
      {
        var button = 0;
        if (typeof(e.which) == "number") { button = e.which; }
        else if(typeof(e.button) == "number") { e = e.button; }
        if (button == 1)
        {
          _dragElement.css("display", "block");
          $(document).bind("mousemove", resizeCallback);
          $(document).bind("mouseup", resizeEndCallback);
        }
        return false;
      }
    );

  _dragElement.addClass("drag");
  _element.append(_dragElement);

  this.getNode = function() { return _element; }

  this.expand = function(e)
  {
    var displayHeight = $(window).height();
    var actualHeight = _element.height();

    var targetHeight = displayHeight - _element.position().top;
    if (targetHeight != actualHeight)
    {
      _element.height(targetHeight);
      _dragElement.height(targetHeight);
    }
  }
}


function VerticalExpander(target, source, subtract)
{
  var _target = $(target);
  var _source = $(source);
  var _subtract = subtract;

  this.expand = function()
  {
    try
    {
      if (_target.is(":visible") && _source.is(":visible"))
      {
        var additional = (_subtract) ? parseInt(_subtract) : 0;
        _target.height(_source.height() - _target.position().top +  _source.position().top - parseInt(_target.css('padding-bottom'))- additional);
      }
    }
    catch (err) { }
  }
}

function FillExpander(target, source, subtract)
{
  var _target = $(target);
  var _source = $(source);
  var _subtract = subtract;
  this.expand = function()
  {
    try
    {
      if (_target.is(":visible") && _source.is(":visible"))
      {
        var additional = (_subtract) ? parseInt(_subtract) : 0;
        _target.height(_source.innerHeight() - additional);
      }
    }
    catch (err) {}
  }
}

function MultiViewControl(id)
{
  var _id = id;
  var _element = $(document.createElement("div"));
  _element.attr("id", _id);
  _element.addClass("multiview");
  _element.data("ActiveViewIndex", -1);

  this.appendView = function(child)
  {
    var childView = $(child);
    if (!childView.hasClass("view"))
    {
      childView.addClass("view");
    }

    _element.append(child);

    if (_element.data("ActiveViewIndex") == -1)
    {
      this.activeViewIndex(0);
    }
  }

  this.activeViewIndex = function(index)
  {
    if (index == null) { return _element.data('ActiveViewIndex'); }
    var oldActive = _element.children(".active");
    oldActive.hide();
    oldActive.removeClass("active");
    var newActive = _element.children().eq(index);
    newActive.addClass("active");
    newActive.show();
    _element.data("ActiveViewIndex", index);
  }

  this.getNode = function() { return _element[0]; }
}

function ConcordanceControl(id, title)
{
  var _element = $(document.createElement("div"));
  _element.attr("id", id);
  _element.text(title);

  this.getNode = function() { return _element[0]; }
}
