var feedback = function (defFeedback_form_subject) {

  var defValues = {
    "feedback_form_textarea": {
      "message": ""
    },
    "feedback_form_email": "",
    "feedback_form_name": "",
    "feedback_form_subject": defFeedback_form_subject,
    "feedback_form_website": ""
  };
  
  var containerId = 'contactRight';
  var buttonSend = 'feedback_button_send';
  var buttons = [ 'feedback_button_send' ];
  
  var mode = "message"; //default
  var modes = ["message"];

  var subjectField = "feedback_form_subject"; //if this is empty, the current mode is the subject
  
  var tabPrefix = "feedback_tab_";
  var server = "/libs/kontaktformular/feedbackgw.php";
  
  var loaderAction = function () {
//     swapDOM("feedback_form",SPAN(null,"..lade.."));
  }
  
  var finishedAction = function (result) {
    if (result.error == "") {
      showElement("feedback_ok");
//       hideElement(buttonSend);
    } else {
      for (var i=0; i<buttons.length; i++) {
        getElement(buttons[i]).disabled=false;
      }
      for (var field in defValues) {
        getElement(field).disabled=false;
      }
      if (result.error == "invalid email") {
        errorAction("feedback_form_email","Bitte prüfen Sie Ihre Email-Adresse!");
      } else {
        errorAction("","Unbekannter Fehler, verzeihung.");
      }
      logFatal("[feedback] Server error: '"+repr(result.error)+"'");
    }
  }
  
  var finishedWithErrorAction = function (){
    for (var i=0; i<buttons.length; i++) {
      getElement(buttons[i]).disabled=false;
    }
    for (var field in defValues) {
      getElement(field).disabled=false;
    }
    errorAction("","Entschuldigung, es gab ein Problem beim Versenden Ihres Reports");
  }
  
  var customSanityChecks = function () {
    return { "mess": "", "field": "" }; //no error
  }
  
  var errorAction = function (field,message) {
    logDebug("showing message '"+message+"'");
    if (!isEmpty(field)) {
      addElementClass(field,"formborder_red");
    }
    replaceChildNodes("feedback_error",message);
    showElement("feedback_error");
    var d = callLater(2,function() { 
        if (navigator.userAgent.indexOf("MSIE 6.0") !== -1) {
            hideElement("feedback_error");
        } else {
            fade("feedback_error");
        }});
  }
  
  
  var defaultState;
  var signalHandlers = [];
  
  var servertoken;

  var checkvalue = function (objId) {
    logDebug("[feedback] checking value for '"+repr(objId)+"'");
    var obj = getElement(objId);
    for (var val in defValues) {
      if (obj.id == val) {
        if ((typeof(defValues[val]) == "object" && obj.value == defValues[val][mode])
        || typeof(defValues[val]) == "string" && obj.value == defValues[val]) {
          logDebug("[feedback] ok, clearing '"+repr(objId)+"'");
          obj.value = "";
        }
      }
    }
    removeElementClass(obj,"formborder_red");
  }
  
  var jumpto = function (newMode) {
    log("[feedback] changing mode from '"+repr(mode)+"' to '"+repr(newMode)+"'");
    var oldmode = mode;
    mode = newMode;
    
    logDebug("[feedback] changing active tab");
    removeElementClass(tabPrefix+oldmode,"feedback_tab_active");
    addElementClass(tabPrefix+oldmode,"feedback_tab_inactive");
    removeElementClass(tabPrefix+mode,"feedback_tab_inactive");
    addElementClass(tabPrefix+mode,"feedback_tab_active");
    
    logDebug("[feedback] changing textarea value, if previously untouched");
    for (var field in defValues) {
      if (typeof(defValues[field]) == "object") {
        if (typeof(defValues[field][mode]) == "string" && (
          defValues[field][oldmode] == getElement(field).value ||
          getElement(field).value == ""
        )) {
          getElement(field).value = defValues[field][mode];
        }
      }
    }
  }
  
  var sanityChecks = function () {
    for (var val in defValues) {
      if (val != "feedback_form_subject" && ((typeof(defValues[val]) == "object" && getElement(val).value == defValues[val][mode])
      || typeof(defValues[val]) == "string" && getElement(val).value == defValues[val]
      || getElement(val).value == "")) {
        return {"mess": "Bitte geben Sie alle Daten an.", "field": val};
      }
    }
    return customSanityChecks();
  }
  
  var sendFeedback = function () {
    var res = sanityChecks();
    if (res.mess != "") {
      errorAction(res.field,res.mess);
      return false;
    }
    log("[feedback] sending feedback now");
    for (var i=0; i<buttons.length; i++) {
      getElement(buttons[i]).disabled=true;
    }
    var message = {"feedback_form_token": servertoken,
      "feedback_form_subj": mode };
    if (!isEmpty(subjectField)) {
        message.feedback_form_subj = getElement(subjectField).value;
    }
    for (var field in defValues) {
      message[field] = getElement(field).value;
      getElement(field).disabled=true;
    }
    loaderAction();
    //build query string
    var url = server+"?";
    var counter =0;
    for (var field in message) {
      if (counter != 0) {
        url = url+"&";
      }
      url = url+field+"="+urlEncode(message[field]);
      counter=counter+1;
    }
    logDebug("ok, query string is '"+repr(url)+"', starting GET");
    var d = loadJSONDoc(url);
    d.addCallbacks(finishedAction, finishedWithErrorAction);
  }
  
  
  this.init = function (newToken) {
    servertoken = newToken;

    logDebug("[feedback] initiating feedback");
    log("[feedback] save default state from element with id '"+containerId+"'");
    defaultState = getElement(containerId).cloneNode(true)
    log("[feedback] setting default values");
    for (var field in defValues) {
      if (typeof(defValues[field]) == "string") {
        logDebug("[feedback] setting value of id '"+field+"' to default value '"+repr(defValues[field])+"'");
        getElement(field).value = defValues[field];
      } else if (typeof(defValues[field]) == "object") {
        logDebug("[feedback] setting value of id '"+field+"' to default value '"+repr(defValues[field][mode])+"' for mode '"+repr(mode)+"'");
        getElement(field).value = defValues[field][mode];
      }
    }
    log("[feedback] connecting signals to clear on focus");
    for (var field in defValues) {
        if (field != "feedback_form_subject") {
            signalHandlers[signalHandlers.length] = connect(field,"onfocus", partial(checkvalue,field));
        }
    }
    if (modes.length > 1) {
        log("[feedback] connecting signals for tabs");
        for (var i=0; i<modes.length; i++) {
            signalHandlers[signalHandlers.length] = connect(tabPrefix+modes[i],"onclick", partial(jumpto,modes[i]));
        }
    }
    log("[feedback] connecting signal for send-button")
    signalHandlers[signalHandlers.length] = connect(buttonSend,"onclick", sendFeedback );
    
    log("[feedback] showing form");
    showElement(containerId);
  }
  
  this.destroy = function () {
    log("[feedback] hiding form");
    hideElement(containerId);
    log("[feedback] resetting state");
    swapDOM(containerId,defaultState);
    log("[feedback] disconnecting signals");
    forEach(signalHandlers,function (ident) { disconnect(ident); });
    signalHandlers = [];
  }
  
}
