function SimpleForm(form_def) {
 if (!$('body').hasClass('flora')) {
  $('body').addClass('flora');
 }
 this.form_def = form_def;
 this.form = $('<form />');
 this.form.append('<div class="form_caption">' + form_def.title + '</div>');
 var div = $('<div class="form_fields" />');
 for (name in form_def.fields) {
  div.append(this.createField(name, form_def.fields[name]));
 }
 this.form.append(div);
 this.form.append(this.createButtons(form_def.buttons));
 this.show();
}

SimpleForm.prototype.show = function() {
// $.blockUI(this.form, {width: $('.form_fields').css('width') + 'px'});
// $.blockUI(this.form, {width: "370px"});
 $.blockUI(this.form, {width: "670px",height: "230px", margin: "-50px 0pt 0pt -325px" });
}

SimpleForm.prototype.createButtons = function(buttons) {
 var div = $('<div class="form_buttons" />');
 for(name in buttons){
  div.append('<input type="button" value="' + name + '">');
 }
 var form = this;
 $('input[type="button"]', div).click(function(){
  var callback = form.form_def.buttons[$(this).val()];
  if (callback in form && typeof form[callback] == 'function') {
   form[callback].call(form);
  }else{
   if (callback in window) {
    window[callback].call(windoiw);
   }
  }
 });
 return div;
}

SimpleForm.prototype.close = function() {
 $.unblockUI();
}

SimpleForm.prototype.ajaxCallback = function(response) {
  response = eval('(' + response + ')');

 if (response.status == 'success') {
  for (name in this.form_def.fields){
   this.setValue(this.form_def.fields[name], $('.modal_field[name="' + name + '"]', this.form).val())
  }
  if ('successCallback' in this.form_def)
   this.form_def['successCallback'].call(window, response);
  this.close();
 }else{
   alert(response.reason);
 }
}

SimpleForm.prototype.submit = function() {
 if (this.validate()) {
  var data = {};
  var action = this.form_def.action;
  $('.modal_field', this.form).each(function(){
   data[$(this).attr('name')] = $(this).val();
  });
  var self = this;
  if (this.form_def.method == 'get'){
   $.get(action, data, function(response){
    self.ajaxCallback(response);
   });
  }else{
   $.post(action, data, function(response){
    self.ajaxCallback(response);
   });
  }
 }else{
  this.showErrors();
 }
}

SimpleForm.prototype.showErrors = function(){
 for (name in this.errors) {
  var text = '<div class="error">' + this.errors[name].join('<br />') + '</div>';
  if (name == 'form')
   $('.form_fields', this.form).before(text);
  else
   $('.modal_field[name="' + name +  '"]', this.form).after(text);

 }
}

SimpleForm.prototype.validate = function() {
 $('.error', this.form).remove();
 this.errors = {};
 _return = true;
 for (name in this.form_def.fields) {
  var field_def = this.form_def.fields[name];
  var errors = new Array();
  if ('validators' in field_def) {
   var value = $('.modal_field[name="' + name +  '"]').val();
   for (var i=0;i<field_def.validators.length; i++) {
    result = false;
    if (field_def.validators[i] in SimpleForm) {
     result =  SimpleForm[field_def.validators[i]].call(window, value);
    }else if (field_def.validators[i] in window){
     result = window[field_def.validators[i]].call(window, value, this.form);
    }
    if (result) {
     errors.push(result);
    }
   }
  }
  if (errors.length) {
   _return = false;
   this.errors[name] = errors;
  }
 }
 if (_return && 'validators' in this.form_def) {
  errors = new Array();
  for (var i=0;i<this.form_def.validators.length;i++) {
   result = window[this.form_def.validators[i]].call(window, this.form);
   if (result)
    errors.push(result);
  }
  if (errors.length) {
   _return = false;
   this.errors.form = errors;
  }
 }
 return _return;
}

SimpleForm.prototype.setValue = function(field_def, value) {
 if ('source' in field_def) {
  var source = $(field_def.source);
  if (source.size()) {
   if (source.attr('tagName').toLowerCase() == 'input') {
    source.val(value);
   }else{
    source.html(value);
   }
  }
 }
}

SimpleForm.prototype.getValue = function(field_def) {
 var value = '';
 if ('source' in field_def) {
  var source = $(field_def.source);
  if (source.size()) {
   var value = (source.attr('tagName').toLowerCase() == 'input')?source.val():source.html();
  }
 }else if ('value' in field_def){
  value = field_def.value;
 }
 return value;
}

SimpleForm.prototype.createField = function(name, field_def) {
 var row = $('<div class="form_row" />');
 value = this.getValue(field_def);
 switch (field_def.type)	 {
  case 'text':
   row.append('<label>' + field_def.title + ':</label>');
   row.append('<input class="modal_field" type="text" name="' + name + '" value="' + value + '" />');
   break;
  case 'password':
   row.append('<label>' + field_def.title + ':</label>');
   row.append('<input class="modal_field" type="password" name="' + name + '" value="" />');
   break;
  case 'hidden':
   row.append('<input class="modal_field" type="hidden" name="' + name + '" value="' + value + '" />');
   break;
  case 'textarea':
   row.append('<label>' + field_def.title + ':</label>');
   var rows = field_def.rows?field_def.rows:5;
   var cols = field_def.cols?field_def.cols:20;
   row.append('<textarea class="modal_field" name="' + name + '">' + value + '</textarea>')
   break;
  case 'select':
   break;
  case 'checkbox':
   break;
  case 'radio':
   break;

 }

 if ('description' in field_def) {
  row.append('<div class="field_description">' + field_def.description + '</div>');
 }
 return row;
}

SimpleForm.urlValidator = function(value) {
 if (!value)
  return '';
 var pattern = /(^http:\/\/|^https:\/\/|^)([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/i;
 if (!pattern.test(value))
  return 'This is not valid URL.';
 return '';
}


SimpleForm.requiredValidator = function(value) {
 if (!value.length)
  return 'This field is required.';
 return '';
}

SimpleForm.emailValidator = function(value) {

 if (!value)
  return '';
 var pattern = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/i;
 if (!pattern.test(value)) {
  return 'This value is not valid email address.';
 }
 return '';
}
