/*
    ajax.js
    Knihovna vseobecnych funkcii pre Ajax
    
    Ajax() - pre obsluhu XMLHttpRequestu (crossbrowser)
    addEvent() - pridanie eventhandleru (crossbrowser)
    removeEvent() - zrusenie eventhandleru (crossbrower)
    Url() - trieda pre url kodovanie a dekodovanie
    Status() - trieda obsluhujica univerzalny dialog pre zobrazenie priebehu Ajax poziadavku
    
    
    pozn:
    & a = mozu sposobit problemy pri prenose, pre utf8 encoded data pouzit encodeURIComponent() namiesto escape()

*/


function Ajax() {
  this.req = null;
  this.url = null;
  this.status = null;
  this.statusText = '';
  this.method = 'GET';
  this.async = true;
  this.dataPayload = null;
  this.readyState = null;
  this.responseText = null;
  this.responseXML = null;
  this.handleResp = null;
  this.responseFormat = 'text', // 'text', 'xml', 'object'
  this.mimeType = null;
  this.headers = [];

  //vytvara XMLHttpRequest pre hlavne prehliadace prehliadace
  this.init = function() {
    var i = 0;
    var reqTry = [ 
      function() { return new XMLHttpRequest(); },
      function() { return new ActiveXObject('Msxml2.XMLHTTP') },
      function() { return new ActiveXObject('Microsoft.XMLHTTP' )} ];
      
    while (!this.req && (i < reqTry.length)) {
      try { 
        this.req = reqTry[i++]();
      } 
      catch(e) {}
    }
    return true;
  };

  //ziada o prevedenie poizadavku typu GET
  this.doGet = function(url, hand, format) {
    this.url = url;
    this.handleResp = hand;
    this.responseFormat = format || 'text';
    this.doReq();
  };

  //ziada o prevedenie poizadavku typu POST
  this.doPost = function(url, dataPayload, hand, format) {
    this.url = url;
    this.dataPayload = dataPayload;
    this.handleResp = hand;
    this.responseFormat = format || 'text';
    this.method = 'POST';
    this.doReq();
  };
  
  //odosle pozadavek asynchronnu poziadavku
  this.doReq = function() {
    var self = null;
    var req = null;
    var headArr = [];
    
    if (!this.init()) {
      alert('Object XMLHttpRequest could not be created!');
      return;
    }
    req = this.req;
    req.open(this.method, this.url, this.async);
    if (this.method == "POST") {
      this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    }
    if (this.method == 'POST') {
      req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); //PND
    }
    self = this;        //obrana proti loose of scope problemu
    req.onreadystatechange = function() {
      var resp = null;
      self.readyState = req.readyState;
      if (req.readyState == 4) {
        
        self.status = req.status;
        self.statusText = req.statusText;
        self.responseText = req.responseText;
        self.responseXML = req.responseXML;
        
        switch(self.responseFormat) {
          case 'text':
            resp = self.responseText;
            break;
          case 'xml':
//            alert(self.responseText + ", XML:" + self.responseXML);
            resp = self.responseXML;
            break;                                 
          case 'object':
            resp = req;
            break;
        }
        
        if (self.status > 199 && self.status < 300) {
          if (!self.handleResp) {
            alert('Handling of this XMLHttpRequest was not defined!');
            return;
          }
          else {
            self.handleResp(resp);         //vola obsluzny handler
          }
        }
        
        else {
          self.handleErr(resp);
        }
      }
    }
    req.send(this.dataPayload);
  };

  this.abort = function() {
    if (this.req) {
      this.req.onreadystatechange = function() { };
      this.req.abort();
      this.req = null;
    }
  };

  //handler informujuci uzivatela o chybe
  this.handleErr = function() {
    var errorWin;
    // zobrazi nove okno s chybou
    try {
      errorWin = window.open('', 'errorWin');
      errorWin.document.body.innerHTML = this.responseText;
    }
    //ak je popup okno blokovane, oznami to uzivatelovi
    catch(e) {
      alert('An error occured. but the error message could not be shown because of the popup blocking by your web browser!\n' +
      'If you want to show the message, please allow the popups for this address.');
    }
  };
  this.setMimeType = function(mimeType) {   //len pre FF, Safari; neda sa pouzit v IE
    this.mimeType = mimeType;
  };
  this.setHandlerResp = function(funcRef) {
    this.handleResp = funcRef;
  };
  this.setHandlerErr = function(funcRef) {
    this.handleErr = funcRef; 
  };
  this.setHandlerBoth = function(funcRef) {
    this.handleResp = funcRef;
    this.handleErr = funcRef;
  };
  this.setRequestHeader = function(headerName, headerValue) {
    this.headers.push(headerName + ': ' + headerValue);
  };
  
}

/*
  Objekt URL prevadza kodovanie a dekodovanie retazca zakodovaneho na server PHP funkcii rawurlencode()
  pouzite z http://www.webtoolkit.info/
*/
var Url = {

	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},

	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},

	// private metoda pro UTF-8 kodovani
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private metoda pro UTF-8 dekodovanie
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}

//pridanie eventhandleru eventu crossbrowserovo
function addEvent(elm, evType, fn)  
{
    if (!elm) {
        alert('element nenalezen, event: ' + evType + ', handler:  ' + fn );
    }    
    if (elm.addEventListener) {                    //DOM standard  
        elm.addEventListener(evType, fn, false);   //posledny parameter: useCapture - zriedka pouzivane, nastavovat na false    
        return true;
    } else if (elm.attachEvent) {
        var r = elm.attachEvent('on' + evType, fn);     //IE6
        return r;
    } else {
        elm['on' + evType] = fn;                        //IE5 pre Mac; ciastecne riesenie - prepisuje predchadzajuce event handlery rovnakeho typu
    }
}    

//odobratie eventhandleru eventu crossbrowserovo
function removeEvent(elm, evType, fn){
    if (elm.removeEventListener){
        elm.removeEventListener(evType, fn, false);
        return true;
    } else if (elm.detachEvent){
        var r = elm.detachEvent("on" + evType, fn);
        return r;
    } else {
        elm['on' + evType] = '';
    }
}


/* 
  status sprava, ako singleton
  Objekt Status() – obsluhuje stavovu spravu informujucu uzivatela o prevedeni poziadavku po zavolani showStatusPrompt()
   z ajaxoveho rozsirenia pri odoslani poziadavku sa zobrazi s dodanym textom v prehliadaci obrazovce a postupnymi bodkami, 
   ktore maju ukazovat prebiehajucu cinnost.
  Po doruceni odpovedi musi ajaxove rozsirenie zavolat hideStatusPrompt() pre skrytie tejto stavovej spravy.
*/
var Status = new function () {
    
    this.initStatus = function() {
        //vytovreni DOM uzlu pre Status
         var self = Status;
        self.statusMessageBox = document.createElement("div");
        self.statusMessageBox.id = "statusMessageBox";
        
        self.msgSpan = document.createElement("span");
        self.msgSpan.id = "statusMessage";
        self.dotSpan = document.createElement("span");
        self.dotSpan.id = "dotSpan";
        
        self.statusMessageBox.appendChild(self.msgSpan);
        self.statusMessageBox.appendChild(self.dotSpan);
                
        var body = document.getElementsByTagName("body")[0];
        body.appendChild(self.statusMessageBox);

        self.statusMessageBox.style.display = "block"; 
    }

     //incializuje Status
     this.showStatusPrompt = function(stat,msg) {
         var self = Status;
      
        self.dots = '';

        self.setStatusMessage(stat, msg);
        self.statusMessageBox.style.display = "block"; // 
        self.promptInterval = window.setInterval(self.showStatusDots, 200);

      }

      
     this.setStatusMessage = function(stat, msg) {
        var self = Status;
        self.statusMessageBox.className = stat + 'Status'; // 'base', 'proc' or 'err'

        if (self.msgSpan.firstChild) {
          self.msgSpan.removeChild(self.msgSpan.firstChild);
        }
        self.msgSpan.appendChild(document.createTextNode(msg));
      }
        
     this.showStatusDots = function() {
        var self = Status;
        
        self.dots += '.';        
        if (self.dots.length > 4) {
          self.dots = '';
        }
        if (self.dotSpan.firstChild) {
          self.dotSpan.removeChild(self.dotSpan.firstChild);
        }                      
        self.dotSpan.appendChild(document.createTextNode(' ' + self.dots));
      }
      
     this.hideStatusPrompt = function() {
        var self = Status;
        window.clearInterval(self.promptInterval);
        
        self.statusMessageBox.style.display = "none"; // 
     }
     
}

/*
  Objekt Recording() umoznuje zaslat skriptu recording.php udaje o nazve, zaciatku a konci akcie. Z nich 
  je vypoitana dlzka trvania operacie
*/
var Recording = new function () {
    this.targetURL = 'recording.php';

    this.start = function(name) {
        var ajax = new Ajax();
        var self = Recording;
        var postData = 'action=start&process=' + name;
        ajax.doPost(self.targetURL, postData, self.handlerFunc); 
    }

    this.end = function(name) {
        var ajax = new Ajax();
        var self = Recording;
        var postData = 'action=end&process=' + name;
        ajax.doPost(self.targetURL, postData, self.handlerFunc); 
    }


    this.handlerFunc = function(resp) {
        //ziadna akcia
    }
    
    
/*    this.start = function(name) {
        var self = Recording;
        var postData = 'action=start&process=' + name;
        self.ajax.doPost(self.targetURL, postData, null); 
    }
*/    
}

addEvent(window,'load',Status.initStatus);      //inicializacia statusu


