function handle_form_change(theElem) {
  validate_width();

  var v = get_form_value(theElem);
  // do no-op if value has not changed
  if (v === theElem.oldValue) { return; }

  // widget dom
  var w = get_widget_dom();
  var $ = get_widget_object();
  var name = theElem.name;
  try {
    if ($.a[name] !== undefined) {
      $.a[name] = v;
    }
    if (name == "width") {
      w.style.width = v + (/\d$/.exec(v) ? "px" : "");
      resize_frame();
    } else if (name == "height") {
      w.style.height = v + (/\d$/.exec(v) ? "px" : "");
      resize_frame();
    } else if (name == "border") {
      w.style.border = v;
      resize_frame();
    } else if (name == "padding") {
      w.c.style.margin = v + (/\d$/.exec(v) ? "px" : "");
      resize_frame();
    } else if (name == "backgroundColor") {
      w.style.backgroundColor = v;
    } else if (name == "titleColor") {
      w.t.style.color = v;
    } else if (name == "titleBackgroundColor") {
      w.h.style.backgroundColor = v;
    } else if (name.indexOf("m_") === 0) {
      var host = document.location.host;
      var url = "http://" + host + "/widget/v1/lt/default";
      var theForm = document.forms['widgetform'];
      for (var i = 0; i < theForm.elements.length; i++) {
        var elem = theForm.elements[i];
        if (elem.name) {
          var value = get_form_value(elem);
          url += "&" + elem.name + "=" + encodeURIComponent(value);
        }
      }
      var previewContainer = document.getElementById("preview-container");
      var jsNode = document.createElement("SCRIPT");
      jsNode.type = "text/javascript";
      jsNode.src = url;
      previewContainer.replaceChild(jsNode, w);
    }
  } catch (e) { }
  // invalidate code
  document.getElementById("jscode").value = "";
  theElem.oldValue = v;
}

function validate_width() {
  var w = get_form_value(document.forms['widgetform'].elements['width']);

  var error = false;
  if (/^\s*\d+\s*%\s*$/.test(w)) {
    // width is percentage; do no-op
  } else if (/^\s*\d+\s*(px)?\s*$/.test(w)) {
    var width = /^\s*(\d+)/.exec(w)[1];
    if (width < 240) {
      w = "240px";
      error = true;
    } else if (width > 700) {
      w = "700px";
      error = true;
    }
  } else {
    w = "300px";
    error = true;
  }
  try {
    if (error) {
      document.forms['widgetform'].elements['width'].value = w;
      document.getElementById('width-helper').style.color = '#f00';
      document.getElementById('width-helper').style.fontWeight = 'bold';
    } else {
      document.getElementById('width-helper').style.color = '#999';
      document.getElementById('width-helper').style.fontWeight = 'normal';
    }
  } catch (e) { }
  return w;
}

function get_js_code() {
  window['_GETCODE_RETRY'] = (window['_GETCODE_RETRY'] === undefined) ?
    1 : window['_GETCODE_RETRY'] + 1;
  var host = document.location.host;
  var url = "http://" + host + "/widget/getcode.php?";
  var theForm = document.forms['widgetform'];
  for (var i = 0; i < theForm.elements.length; i++) {
    var theElem = theForm.elements[i];
    var name = theElem.name;
    if (name) {
      if (name != 'module' && name.indexOf("m_") != 0) {
        name = "c_" + name;
      }
      var value = get_form_value(theElem);
      url += name + "=" + encodeURIComponent(value) + "&";
    }
  }
  url = url.replace(/&$/, '');
  YAHOO.util.Connect.asyncRequest('GET', url, get_js_callback, null);
}

function resize_frame() {
}

function get_form_value(elem) {
  if (elem.type == 'checkbox') {
    return elem.checked ? "true" : "false";
  }
  if (elem.type == 'select' || elem.type == 'select-multiple') {
    var v = [];
    for (var i = 0; i < elem.options.length; i++) {
      if (elem.options[i].selected) {
        v[v.length] = elem.options[i].value;
      }
    }
    return v.join(",");
  }
  return elem.value;
}

function get_widget_object() {
  // the widget is the first child of "preview"
  var w = document.getElementById("preview-container").firstChild;
  // get the true name of the widget
  var trueName = w.className.split(/\s+/)[0];
  return window[trueName];
}

function get_widget_dom() {
  return document.getElementById("preview-container").firstChild;
}

function init_options_form() {
  // the beloved $
  var $ = get_widget_object();

  // the form
  var theForm = document.forms['widgetform'];

  // chrome styles
  for (var s in $.a) {
    if (theForm[s] !== undefined) {
      theForm[s].value = $.a[s];

      if (s == 'width') {
        theForm[s].focus();
        theForm[s].select();
      }
    }
  }

  // remember state
  for (var i = 0; i < theForm.elements.length; i++) {
    var elem = theForm.elements[i];
    elem.iniValue = elem.oldValue = get_form_value(elem);
  }
}

var get_js_callback = {
  success : function(o) {
    var js = o.responseText.replace(/ +/g, ' ').replace(/\r/g, '').replace(/\n/g, '');
    var container = document.getElementById("jscode");
    container.value = js;
    container.focus();
    container.select();
  },

  failure : function(o) {
    // retry three times; then display an error message
    if (window['_GETCODE_RETRY'] < 3) {
      get_js_code();
    } else {
      document.getElementById("jscode").value =
        "Error: Cannot retrieve code for the widget. Please try again later.";
    }
  }
};

var check_widget_status = function() {
  var p = document.getElementById("preview");
  if (p.firstChild.tagName == "SCRIPT") {
    window.setTimeout(check_widget_status, 100);
  } else {
    init_options_form();
  }
};
window.setTimeout(check_widget_status, 100);
