function HtmlDocument__makeControlPane (formid, cssUri)
{
  if (!cssUri)
    cssUri = window.top.CSS_PATH + "dialog.css";

  return this._makeControlPaneEx (formid, cssUri, null);
}

function HtmlDocument__makeControlPaneEx (formid, cssUri, defaultCss)
{
  if (!cssUri) {
    if (!defaultCss)
      cssUri = window.top.CSS_PATH + "dialog.css";
    else
      cssUri = window.top.CSS_PATH + defaultCss;
  }

  this.createStyleSheet (cssUri);
  var body = window.top._customizeBody (this._body);
  body.onclick = null;
  var frm = this._form (formid);

  frm._clear         = Container__clear;
  frm._addControl    = Container__addControl;
  frm._removeControl = Container__removeControl;

  return body.appendChild (frm);
}

function Container__clear()
{
  var length = this.childNodes.length;
  for (var i = 0; i < length; i++)
    this.removeChild (this.firstChild);
}

function Container__addControl (ctrl, parentNode)
{
  ctrl._parent = this;
  if (!parentNode)
    parentNode = this;

  parentNode.appendChild (ctrl);
  return ctrl;
}

function Container__removeControl (id)
{
  var doc = this.ownerDocument;
  var ctrl = doc.getElementById (id);
  if (ctrl)
    this.removeChild (ctrl);
}

function Container__getControl (id)
{
  var doc = this.ownerDocument;
  return doc.getElementById (id);
}


function Control__scrollIntoView ()
{
  _scrollIntoView (this, this.ownerDocument._body);
}


function _customizeControl (ctrl)
{
  var doc = ctrl.ownerDocument;
  if (doc._isIE)
    ctrl.onactivate = __ctrl_onfocus__;
  else
    ctrl.onfocus = __ctrl_onfocus__;
  ctrl._scrollIntoView = Control__scrollIntoView;
}

function __ctrl_onfocus__ (event)
{
  var ctrl = this;
  while (ctrl._parent) {
    var parent = ctrl._parent;
    parent._focus = ctrl;
    ctrl = parent;
  }
}



function HtmlDocument__hyperlink (id, name, label, url, mode)
{
  var a = this.createElement ("a");
  a.href = "";
  a.id = id;
  a.name = name;
  a._label = label;
  a._url = url;
  a._mode = mode;
  a.onclick = Hyperlink__processOnClick;
  a.innerHTML = label;
  a._setTabIndex = HtmlDocument__setTabIndex;
  return a;
}

function Hyperlink__processOnClick ()
{
  window.top._executeRequest ('hyperlink');
  return false;
}

function HtmlDocument__button (id, name, caption)
{
  var b = this._input (id, 'button', name, caption);
  b.onclick = Button__processOnClick;
  b.__processOnKeyPress__ = Button__processOnKeyPress;
  b._setDefault = Button__setDefault;
  return b;
}

function HtmlDocument__imageButton (id, name, imageRef)
{
  var img = this.createElement("img");
  img.id = id;
  img.name = name;
  img._imageRef = imageRef;
  img.src = imageRef['default'];
  img.onmouseover=ImageButton_onmouseover;
  img.onmouseout=ImageButton_onmouseout;
  img.onmousedown=ImageButton_onmousedown;
  img.onmouseup=ImageButton_onmouseup;
  img.onclick = Button__processOnClick;
  img._setTabIndex = HtmlDocument__setTabIndex;
  img._setDefault = Button__setDefault;
  return img;
}

function Button__processOnKeyPress()
{
  return true;
}

function Button__setDefault (isDefault)
{
  if (isDefault == true && window.top.DEFAULT_BUTTON != this) {
    window.top.DEFAULT_BUTTON = this;
    var btn = this;

    var span = btn.ownerDocument.createElement ("span");
    var parent = btn.parentNode;
    span.appendChild (btn);
    parent.appendChild (span);

    span.className="default";
    span.style.position = 'absolute';
    span.style.left = btn.style.left;
    span.style.top = btn.style.top;

    btn.style.position = '';
    btn.style.width = (btn.offsetWidth-2) + "px";
    btn.style.height = (btn.offsetHeight-2) + "px";

    addEventTo (
      window.top, 'resize',
      function() {
        span.style.left = btn.style.left;
        span.style.top = btn.style.top;
        btn.style.left = "0";
        btn.style.top = "0";
      }
    );

  }
  else {
    if (window.top.DEFAULT_BUTTON == this)
      window.top.DEFAULT_BUTTON = null;
  }
}


function Button__processOnClick()
{
  if (this.disabled)
    return false;

  var win = window.top;
  var type = this._actionType;
  if (type == 'cancel')
    win._endModal();
  else if (type == 'ok')
    win._finishDialog();
  else
    win._executeRequest (this.name, this._formToSubmit);
  return false;
}

function ImageButton_onmouseover () { this.src = this._imageRef['hilite'];  }
function ImageButton_onmouseout  () { this.src = this._imageRef['default']; }
function ImageButton_onmousedown () { this.src = this._imageRef['active'];  }
function ImageButton_onmouseup   () { this.src = this._imageRef['hilite'];  }


function HtmlDocument__select (id, name)
{
  var select = this.createElement ("select");
  select.id   = id;
  select.name = name;
  select._name = name;

  select._addOption     = Select__addOption;
  select._clear         = Select__clear;
  select._removeByIndex = Select__removeByIndex;
  select._removeByName  = Select__removeByName;
  select._selectAll     = Select__selectAll;
  select._selectByIndex = Select__selectByIndex;
  select._selectByName  = Select__selectByName;
  select._focus         = Select__focus;
  select._setTabIndex   = HtmlDocument__setTabIndex;

  select.onchange = Select_onchange;

  return select;
}


function Select__addOption (name, caption, isSelected, index)
{
  var opt = this.ownerDocument.createElement ("option");
  opt.value     = name;
  opt.text      = caption;
  opt.selected  = isSelected;
  if (index == -1)
    this.options.add (opt);
  else
    this.options.add (opt, index);
  return opt;
}


function Select__clear ()
{
  var options = this.options;
  for (i = options.length - 1; i >= 0; i--)
    this.removeChild (options[i]);
}

function Select__removeByIndex (index)
{
  this.removeChild (this.options[i]);
}

function Select__removeByName (name)
{
  var options = this.options;
  for (i = options.length - 1; i >= 0; i--) {
    var opt = options[i];
    if (opt.value == name)
      this.removeChild (options[i]);
  }
}


function Select__selectAll (isSelect)
{
  var options = this.options;
  if ( !(isSelect || this.multiple) )
    this.selectedIndex = -1;
  else
    for (i = options.length - 1; i >= 0; i--)
      options[i].selected = isSelect;
}

function Select__selectByIndex (isSelect, index)
{
  var opt = this.options[index];
  if (opt)
    opt.selected = isSelect;
}

function Select__selectByName (isSelect, name)
{
  var options = this.options;
  for (i = options.length - 1; i >= 0; i--) {
    var opt = options[i];
    if (opt.value == name)
      opt.selected = isSelect;
  }
}


function Select__focus ()
{
  var focusIndex = this.selectedIndex;
  if (focusIndex != -1)
    return this.options[focusIndex].value;

  return null;
}


function Select_onchange ()
{
  if (this._enableEvents)
    window.top._executeRequest (this.name);
}

// Label
function HtmlDocument__label (id, name, innerHtml, accessKey, controlid)
{
  var label = this.createElement ("label");
  label.setAttribute ('id', id);
  label.setAttribute ('name', name);
  label.innerHTML = innerHtml;
  if (accessKey)
    label.accessKey = accessKey;
  label.htmlFor = controlid;
  label.style.padding = "4px 0 0 4px";
  label._name = name;
  return label;
}

// TextArea
function HtmlDocument__textArea (id, name, value)
{
  var textArea = this.createElement ('textarea');
  textArea.setAttribute ('id', id);
  textArea.setAttribute ('name', name);
  textArea.setAttribute ('_name', name);
  textArea.setAttribute ('value', value);
  textArea._setTabIndex = HtmlDocument__setTabIndex;
  textArea.onkeypress = TextArea__onkeypress__;
  return textArea;
}

function TextArea__onkeypress__()
{
  var event = this.ownerDocument.parentWindow.event;
  if (event.stopPropagation)
    event.stopPropagation();

  if (event.keyCode == 10 && event.ctrlKey) {
    event.keyCode = 13;
    event.cancelBubble = true;
  }
}

// CheckBox
function HtmlDocument__checkBox (id, name, value)
{
  var cb = this._input (id, 'checkbox', name);
  cb.checked = value;
  cb.onclick = CheckBox__processOnClick;
  cb._generateEvents = false;
  cb._setTabIndex = HtmlDocument__setTabIndex;
  return cb;
}

function CheckBox__processOnClick ()
{
  if (this._generateEvents)
    window.top._executeRequest (this.name);
}

// RadioGroup
function HtmlDocument__radioGroup (id, name, layout)
{
  var group = this.createElement ("div");
  group.style.verticalAlign="middle";
  group.className = "radio";
  group.id = id;
  group.name = name;
  group.style.overflow = 'hidden';

  group._doc = this;
  group._layout = layout;

  group._setEnabled       = RadioGroup__setEnabled;
  group._addButton        = RadioGroup__addButton;
  group._findButton       = RadioGroup__findButton;
  group._selectByIndex    = RadioGroup__selectByIndex;
  group._selectByName     = RadioGroup__selectByName;
  group._setEnabledByName = RadioGroup__setEnabledByName;
  group._enable           = RadioGroup__enable;
  group._setValue         = RadioGroup__selectByIndex;
  group._arrangeTabIndex  = RadioGroup__arrangeTabIndex;
  group._selectedButtonId = null;
  group._generateEvents   = false;

  group.appendChild (this.createElement('nobr'));
  return group;
}

function RadioGroup__setEnabled (enabled)
{
  this.disabled = !enabled;
  var childNodes = this.firstChild.childNodes;
  for (var i = childNodes.length - 1; i >= 0; i--) {
    var child = childNodes[i].firstChild;
    child.disabled = !enabled;
  }
}

function RadioGroup__addButton (buttonName, buttonCaption, accessKey)
{
  var doc = this._doc;
  var child = doc.createElement (this._layout == 'v' ? 'div' : 'span');

  child.style.verticalAlign="middle";
  var id = this.id;
  child.id = id + buttonName;
  this.firstChild.appendChild (child);
  var buttonId = "btn_" + id + buttonName;
  var input = child.appendChild (doc._input (buttonId, 'radio', id, id));
  input.onclick = RadioGroupButton___processOnClick;
  child.appendChild (doc._label (null, null, buttonCaption, accessKey, buttonId));
}


function RadioGroup__selectByName (buttonName)
{
  var button = this._findButton (buttonName);
  if (button)
    button.checked = true;
}

function RadioGroup__findButton (buttonName)
{
  var id = this.id + buttonName;
  var childNodes = this.firstChild.childNodes;
  for (var i = childNodes.length - 1; i >= 0; i--) {
    var child = childNodes[i];
    if (child.id == id)
      return child.firstChild;
  }
  return null;
}

function RadioGroup__setEnabledByName (buttonName, enabled)
{
  var button = this._findButton (buttonName);
  if (button)
    button.disabled = !enabled;
}


function RadioGroup__selectByIndex (index)
{
  var child = this.firstChild.childNodes[index];
  if (child) {
    var node = child.firstChild;
    node.checked = true;
  }
}

function RadioGroup__enable (enable)
{
  var childNodes = this.firstChild.childNodes;
  for (var i = childNodes.length - 1; i >= 0; i--)
    childNodes[i].disabled = !enable;
}

function RadioGroup__arrangeTabIndex (startTabIndex)
{
  var childNodes = this.firstChild.childNodes;
  for (var i = childNodes.length - 1; i >= 0; i--)
    childNodes[i].lastChild.tabIndex = startTabIndex + i;
}

function RadioGroupButton___processOnClick ()
{
  var group = this.parentNode.parentNode.parentNode;

  if (group._generateEvents) {
    if (this.id != group._selectedButtonId) {
      group._selectedButtonId = this.id;
      window.top._executeRequest (group.name);
    }
  }

  return true;
}

//Block
function HtmlDocument__block (id, name)
{
  var block = this.createElement ("div");

  block.id   = id;
  block.name = name;

  block.__processOnContextMenu__ = Block___processOnContextMenu__;

  block._clear         = Container__clear;
  block._addControl    = Container__addControl;
  block._removeControl = Container__removeControl;
  block._getControl    = Container__getControl;

  block._setEnabled     = Block__setEnabled;
  block._createElement  = Block__createElement;
  block._createTextNode = Block__createTextNode;

  return block;
}

function Block__setEnabled (enabled)
{
  Block__elementSetEnabled (this, enabled);
}

function Block__elementSetEnabled (elm, enabled)
{
  var childNodes = elm.childNodes;
  if (!childNodes)
    return;

  var n = childNodes.length;
  for (var i = 0; i < n; ++i) {
    var child = childNodes[i];
    if (child._setEnabled)
      child._setEnabled (enabled);
    else if (child._classid)
      child.disabled = !enabled;
    else
      Block__elementSetEnabled (child, enabled);
  }
}

function Block__createElement (name)
{
  var doc = this.ownerDocument;
  return doc.createElement (name);
}

function Block__createTextNode (text)
{
  var doc = this.ownerDocument;
  return doc.createTextNode (text);
}

function Block___processOnContextMenu__ (doc, event)
{
  window.top._openContextMenu ("BLOCK;" + this._contextMenu, doc, event);
  return false;
}

//------------------------------------------------------------------------
// getState()
//------------------------------------------------------------------------

function ContainerPane__getState()
{
  var state = Widget__getState.call (this);
  var frm = this._form;
  var focus = frm._focus;
  state.setAttribute ('focus', focus ? focus.id : null);
  Container__getChildStates (state, frm);
  return state;
}


function Container__getChildStates (state, elm)
{
  var stack = [];
  stack.push (new State__stackEntry (state, elm.childNodes));

  loop:
  while (stack.length > 0) {
    var entry = stack [stack.length - 1];
    var state    = entry._state;
    var children = entry._children;
    var pointer  = entry._pointer;

    var n = children.length;
    for (var i = pointer; i < n; ++i) {
      var child = children[i];
      var nextState = state;
      if (child._getState) {
        nextState = child._getState();
        state.addChild (nextState);
      }

      var childNodes = child.childNodes;
      if (childNodes) {
        entry._pointer = i + 1;
        stack.push (new State__stackEntry (nextState, childNodes));
        continue loop;
      }
    }
    stack.pop();
  }
}

function Control__getState()
{
  var state = GuiObject__getState.call (this, "control");
  if (this.value) {
    var value = new XmlElementNode ("value");
    value.addText (this.value);
    state.addChild (value);
  }
  state.setAttribute ("enabled", !this.disabled)
  state.setAttribute ("visible", !this.style.visibility == 'visible' ? 'true' : 'false');
  return state;
}

function Container__getState()
{
  var state = Control__getState.call (this);
  var focus = this._focus;
  state.setAttribute ('focus', focus ? focus.id : null);
  return state;
}

function Select__getState()
{
  var state = Control__getState.call (this);
  if (this._returnItems)
    state.setAttribute ("returnItems", "true");
  if (this._enableEvents)
    state.setAttribute ("enableEvents", "true");
  if (this.multiple)
    state.setAttribute ("multiple", "true");

  var options = this.options;
  for (i = 0; i < options.length; i++) {
    var opt = options[i];
    if (opt.selected) {
      var node = new XmlElementNode ("s");
      node.addText (opt.value);
      state.addChild (node);
    }
    if (this._returnItems) {
      var node = new XmlElementNode ("i");
      node.addText (opt.value);
      state.addChild (node);
    }
  }
  return state;
}

function Label__getState()
{
  var state = Control__getState.call (this);
  state.setAttribute ('name', this._name);
  return state;
}

function CheckBox__getState()
{
  var state = Control__getState.call (this);
  if (this.checked)
    state.setAttribute ("checked", "true");
  return state;
}

function RadioGroup__getState()
{
  var state = Control__getState.call (this);
  state.setAttribute ("btnCount", this._btnCount);
  var childNodes = this.firstChild.childNodes;
  for (var i = childNodes.length - 1; i >= 0; i--) {
    var child = childNodes[i].firstChild;
    if (child.checked) {
      state.setAttribute ("selection", child.id.substr (this.id.length + "btn_".length));
      break;
    }
  }
  return state;
}

function Button__getState()
{
  var state = Control__getState.call (this);
  if (this._formToSubmit)
    state.setAttribute ("id-to-submit", this._formToSubmit);
  return state;
}

function Hyperlink__getState()
{
  var state = Control__getState.call (this);
  state.setAttribute ("hyperlinkUrl", this._url);
  state.setAttribute ("hyperlinkMode", this._mode);
  return state;
}
