  
/*
 * ekvivalent k PHP trim (bez druheho parametru) zdroj: jquery 
 * @param string arg
 * @return arg
 */
function trim(arg) {
  return (arg || '').replace( /^\s+|\s+$/g, '');
}

/*
 * ekvivalent k PHP in_array (bez tretiho parametru)
 * @param string needle
 * @param array haystack      
 */
function in_array(needle, haystack) {  
  for (i in haystack) {
    if (needle == haystack[i]) {
      return true;
    }
  }
  return false;  
}

/*
 * CheckForm
 * *** objekt na kontrolu formularu ***  
 * copyright 2009 Michal Sobola
 * posledni revize 16.4. 2009
 * 
 * nasazeni :
 * zakomentovane metody jsou nepovinne 
 */

/*
  CheckForm.setBorders('red','#aaa'); // prvni je cerveny, druhy vychozi
  // CheckForm.setDebug(0); // chceme zakazat vypis chyb (vychozi je 1)
  // CheckForm.setImages(); // je-li ze zavolano bez argumentu, bereme vychozi url obrazku
  // CheckForm.setMessages('Following required field was emtpy:', 'Following field has wrong format:'); // pokud chceme prekladat chybove hlasky
  CheckForm.setForm('id_formulare'); // nastavime ID formulare
  
  // za kazdy input jedno zavolani metody - lepe provadet v cyklu
  CheckForm.setField('name', 'text', 'Jméno:');
  CheckForm.setField('email', 'text', 'Email:', 'email');
  CheckForm.setField('text', 'textarea', 'Text zprávy:');

  // CheckForm.textareaResizer('images/resize.gif', 'class_name'); // budeme nebo nebudeme resizovat textarey - mozno volat bez argumentu
*/

var CheckForm = {

  // debug - vypis chyb
  debug : 1,
 
  // ramecky inputu - prvni je cerveny, druhy je vychozi
  borders : ['red', '#aaa'],

  // regulary
  objRegExp : {
    'email' : /^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/i,
    'psc' : /^([0-9.]{5,6}|[0-9 ]{5,6})$/i,
    'phone' : /^[+]?[()/0-9. -]{9,30}$/i,
    'phone_strict' : /^\+([0-9]{12})$/i,
    'login' : /^[.]{5,}$/i,
    'passwd' : /^[.]{6,}$/i
  },
  
  // chybove hlasky
  messages : {
    'empty' : 'Následující povinná položka nebyla vyplněna:',
    'wrong' : 'Následující položka má špatný formát:'
  },
  
  // objekt formulare, ziskany z getElementById
  formular : null,
  
  // id formulare, ktery budeme kontrolovat
  formId : '',
  
  // povinne polozky
  fields : {},
  
  // chyby
  formErrors : '',
  
  // pouze kontrola typu
  types : ['text', 'password', 'checkbox', 'radio', 'select', 'textarea'],
  
  // obrazky
  images : false,

  // pokud je polozka spatne, zahlas hned chybu
  alertOnError : false,
  
  // image id prefix
  imageIdPrefix : 'form_image_',
  
  // trida obrazku
  imageClassName : 'validation_img',

  /*
   * aktivuje debug : vypis chyb
   * @param int debug   
   */
  setDebug : function(debug) {
    this.debug = debug;
  },

  /*
   * nastavi ramecky
   * @param string red_border
   * @param string [default_border]      
   */   
  setBorders : function(red_border, default_border) {
    this.borders[0] = red_border;
    if (default_border !== undefined) {
      this.borders[1] = default_border;
    }
  },
  

  /*
   * nastavi hlasky
   * @param string msg1 - nevyplnena polozka
   * @param string [msg2] - spatny format polozky
   */
  setMessages : function(msg1, msg2) {
    this.messages.empty = msg1;
    if (msg2 !== undefined) {
      this.messages.wrong = msg2;
    }
  },
  
  /*
   * nastavi krizky a fajky za inputem
   * @param string trueImage url obrazku
   * @param string falseImage url obrazku      
   */  
  setImages : function(trueImage, falseImage) {
    if (trueImage === undefined) {
      trueImage = 'images/true.gif';
    }
    if (falseImage === undefined) {
      falseImage = 'images/false.gif';
    }
    this.images = {
      'true' : trueImage,
      'false' : falseImage
    }
  },

  /*
   * nastavi objekt formulare
   * nastavi formulari akci na onsubmit
   * nastavi vse ve formulari   
   * @param string formId   
   */
  setForm : function(formId) {
    this.formId = formId;
    this.formular = document.getElementById(formId);
    if (this.formular !== null) {
      this.formular.onsubmit = function () {
        return (!CheckForm.checkOnSubmit() ? false : true);
      }
    } else if (this.debug) {
      return document.writeln('<span style="color:red">Form of id <strong>' + formId + '</strong> is null.</span><br />');
    } else {
      return true;
    }
  },

  /*
   * nastavi povinne pole, kt. budeme kontrolovat
   * @param string name
   * @param string type [text, password, checkbox, radio, select, textarea]
   * @param string label
   * @param string regexp klic k poli objRegExp   
   * @param string [id] if undefined, prepokladame id == name        
   */
  setField : function(name, type, label, regexp, id) {
  
    // kontrola nepovinnych parametru
    if (id === undefined) {
      id = name;
    }
    
    if (type == 'bool') {
      type = 'checkbox';
    }
    
    // kontrola regularu
    if (regexp === undefined || !regexp) {
      regexp = null;
    } else {
      if (!this.objRegExp[regexp]) {
        if (this.debug == 1) {
          document.writeln('<span style="color:red">Invalid RegExp name: <strong>' + regexp + '</strong>. Check the <em>objRegExp</em> variable.</span><br />');
        }
        regexp = null;
      }
    }
    
    // kontrola typu
    if (!in_array(type, this.types)) {
      if (this.debug == 1) {
        document.writeln('<span style="color:red">Not a supported field type <strong>' + type + '</strong>. Check the <em>types</em> variable.</span><br />');
      }
      return true;
    }
    
    // kontrola existence prvku
    object = document.getElementById(id);
    if (object === null && type != 'radio') {
      if (this.debug == 1) {
        return document.writeln('<span style="color:red">document.getElementById(' + id + ') is null. Will not check this field.</span><br />');
      } else {
        return true;
      }
    }
    
    // kontrola spravnosti nacteneho prvku
    if (object !== null && object.tagName != 'INPUT' && object.tagName != 'SELECT' && object.tagName != 'TEXTAREA') {
      if (this.debug == 1) {
        return document.writeln('<span style="color:red">Element of id <strong>' + id + '</strong> is not valid form element. Duplicate id possible.</span><br />');
      } else {
        return true;
      }
    }
    
    // kontrola jestli budeme za input generovat krizky a fajfky, pridani akci polozce
    if (this.images && type != 'radio') {
      try {
        newImage = document.createElement('img');
        newImage.setAttribute('alt', '#');
        newImage.setAttribute('id', this.imageIdPrefix + id);
        newImage.setAttribute('class', this.imageClassName); 
        newImage.setAttribute('src', this.images[(this.checkIt(object, regexp) ? 'true' : 'false')]);
        this.insertAfter(newImage, object);
      } catch (err) {
        if (this.debug == 1) {
          document.writeln('<span style="color:red">' + err + '</span><br />');
        }
      }

      if (object.type == 'checkbox' || type == 'select' || type == 'radio') {
		object.onclick = function() { CheckForm.checkFieldAndSetBorder(this); };
		object.onchange = function() { CheckForm.checkFieldAndSetBorder(this); };
      } else {
		object.onkeyup = function() { CheckForm.checkField(this); };
		object.onblur = function() { CheckForm.checkFieldAndSetBorder(this); };
      }
    }
    
    // prirazeni inputu do pole
    this.fields[id] = { 'name' : name, 'type' : type, 'label' : label, 'object' : object, 'regexp' : regexp };
  },
  
  /*
   * kontrola inputu kdyz se do nej pise, konci zavolanim funkce o jedno niz
   */
  checkField : function(object) {
    image = document.getElementById(this.imageIdPrefix + (object.id ? object.id : object.name));
	var result = this.checkIt(object);

	if (this.alertOnError) {
	  if (!result && object.value=='') {
		  alert(this.messages[empty]);
	  } else if (!result) {
		  alert(this.messages[error]);
	  }
	}

    if (image) {
      source = (result ? 'true' : 'false');
      if (source == 'true' && this.borders[1]) {
         object.style.borderColor = this.borders[1];
      }

      return image.src = this.images[source];
    } else {
      return true;
    }
  },

  /*
   * kontrola inputu kdyz se do nej pise, konci zavolanim funkce o jedno niz
   */
  checkFieldAndSetBorder : function(object) {
	check = this.checkIt(object);
	if (check && this.borders[1]) {
		object.style.borderColor = this.borders[1];
	} else if (!check && this.borders[0]) {
		object.style.borderColor = this.borders[0];
	}
    this.checkField(object);
  },

  
  /*
   * kontrola value, volano vnitrne
   */
  checkIt : function(object, regexp) {
    if (regexp === undefined) {
      regexp = this.fields[object.id]['regexp']
    }
    if (object.type == 'checkbox') {
      return object.checked;
    } else {
      if (regexp !== null) {
        return this.testRegExp(regexp, object.value);
      } else {
        return object.value != '' ? true : false;
      }
    }
  },

  /*
   * vytvori element za jinym elementem
   * @param object document.getElementById(rodic)
   * @param object document.createElement(vysledek)
   * @param object document.getElementById(objekt)
   */
  insertAfter : function (item, referenceNode) {
    referenceNode.parentNode.insertBefore(item, referenceNode.nextSibling);
  },

  /*
   * test regularu
   * @param ref klic pole this.objRegExp
   * @param value testovana hodnota      
   */
  testRegExp : function(ref, value) {
    return this.objRegExp[ref].test(value) ? true : false;
  },

  /*
   * kontrola po odeslani formulare
   */
  checkOnSubmit : function() {
    try {
      for (var i in this.fields) {
        error = 0;
        if (this.fields[i].type == 'checkbox') {
          if (this.fields[i]['object'].checked === false && !this.fields[i]['object'].disabled) {
            error = 'empty';
          }
        } else if (this.fields[i].type == 'radio') {
          inputs = this.formular.getElementsByTagName('input');
          
	  for (j in inputs) {
		if (!this.fields[i]['object'].disabled) {
		      error = 'empty';
		      break;
		}
	  }
          for (j in inputs) {
            if (this.fields[i].name == inputs[j].name && inputs[j].checked === true) {
              error = 0;
              break;
            }
          }
        } else {
          value = trim(this.fields[i]['object'].value);
          if (value == '' && !this.fields[i]['object'].disabled) {
            error = 'empty';
          }
          if (this.fields[i]['regexp'] && !this.testRegExp(this.fields[i]['regexp'], value) && !this.fields[i]['object'].disabled) {
            error = 'wrong';
          }
          if (this.borders[0] && this.borders[1]) {
            this.fields[i]['object'].style.borderColor = this.borders[(error == 0 ? 1 : 0)];
          }
        }
        if (error != 0) {
          this.formErrors += this.messages[error] + ' ' + this.fields[i]['label'] + "\n";
        }
      }
      if (this.formErrors != '') {
        alert(this.formErrors);
        this.formErrors = '';
        return false;
      } else {
        return true;
      }
    } catch (err) {
      if (this.debug == 1) {
        alert(err);
        return false;
      } else {
        return true;
      }
    }
  }, 
  
  /*
   * textarea resizer
   * zdroj: 4umi.com/web/javascript/textarearesize.htm
   * modifikovano pro resizovani vice textarei pod sebou, povoleni smeru pouze nahoru a dolu   
   */
  textareaResizer : function(bgImg, resizerClassName) {
    if (!bgImg) {
      bgImg = 'images/resize.gif';
    }
    if (!resizerClassName) {
      resizerClassName = 'textarea_resizer';
    }
  
    // zmena pozice prvku
    function loopPositions(obj) {
      var x = 0, y = 0;
      do {
        x += obj.offsetLeft;
        y += obj.offsetTop;
      } while (obj = obj.offsetParent);
      
      if (document.all) {
        return { x:(x+3), y:(y+1) };
      } else {
        return { x:x, y:(y-1) };
      }
    }
    
    // zachyceni udalosti
    function g(e) {
      e = e || window.event || {};
      return 'number' === typeof e.clientY ? { x:e.clientX, y:e.clientY } : { x:e.x, y:e.y };
    }
    
    // zmena stylu - zpravidla vlastnosti top, left, height, width
    function changeStyleValue(obj, style, value) {
      obj.style[style] = Math.max(1, value) + 'px';
    }
    
    var m = document.createElement('div'), o, p, s = 11, sh = 10, t, x = s + 'px', y = sh + 'px';
    
    a = document.getElementsByTagName('textarea');
    i = a.length;
    
    // obecne styly pro vsechny resizery, lze zmenit v css dle tridy, nutne vsak dodat !important
    m.style.background = 'url(' + bgImg + ') no-repeat 0 0';
    m.style.cursor = 'n-resize';
    m.style.position = 'relative';
    m.style.cssFloat = 'left';
    m.style.width = '11px';
    m.style.height = '11px';
    if (document.all) {
      m.style.left = '-13px';
    } else {
      m.style.left = '-11px';
    }
    
    m.className = resizerClassName; 

    // od spoda nahoru projizdime vsechny textarey
    while(i--) {
      t = a[i];
      p = loopPositions(t);
      
      // naklonujeme prvek, kt. jsme si predvytorili
      o = m.cloneNode(true);
      
      // pridame nejake dalsi styly
      o.style.top = t.offsetHeight-11 + 'px';

      // kazdemu nove vytvorenemu prvku pridame akci
      o.onmousedown = function(evt) {
        ob = this;
        p = loopPositions(ob);
        q = g(evt);
        ob.oX = q.x-p.x;
        ob.oY = q.y-p.y;

        // pohybujeme kurzorem
        document.onmousemove = function(e) {
          // textarea je hned pred resizerem
          p = loopPositions(ob.previousSibling);
          q = g(e);
          
          // resizneme textareu
          changeStyleValue(ob.previousSibling, 'height', Math.max(sh, q.y-ob.oY-p.y+6));

          // posuneme dolu
          ob.style.top = ob.previousSibling.offsetHeight-11 + 'px'; 
        };
        
        document.onselectstart = function() {
          return false;
        };
        
        // pusteni mysitka
        document.onmouseup = function() {
          ob = null;
          document.onmousemove = null;
          document.onselectstart = null;
          document.onmouseup = null;

          // osetreni, pac to blbne kdyz chci resizovat 2x po sobe (bylo nutne kliknout pryc)
          document.body.focus();
        };
      };

      // vytvorime prvek hned za textareou
      this.insertAfter(o, t);
    }
  }
};

