var reddevil = reddevil || {};
reddevil.i18n = {};
reddevil.lang = 'en';

reddevil._ = function(str) {
    if (str in reddevil.i18n[reddevil.lang])
        return reddevil.i18n[reddevil.lang][str];
    return reddevil.i18n.en[str]
}

// json: a class providing json functionality on top of ajax
//  2 public functions
//  - uploadFile: uploading a File
//  - rpc: performing a rpc call on the server using jsonrpc v2.0

reddevil.json = function(){this.init(this);};
(function(){
    var self;
    function init(obj) {
        self=obj;
        self.http = null;
        if (window.XMLHttpRequest)
            self.http = new XMLHttpRequest();
        else if (window.ActiveXObject)
            self.http = new ActiveXObject("Microsoft.XMLHTTP");
    };
    function uploadFile(url, file, kw) {
        if (reddevil.console)
            console.log('uploadfile:',url, file);
        if (!self.http) return false;
        self.url = url;
        self.onSuccess = kw.onSuccess ? kw.onSuccess : null;
        self.onError = kw.onError ? kw.onError : null;
        self.onProgress = kw.onProgress? kw.onProgress : null;
        self.timeout = kw.timeout ? kw.timeout : 0;
        self.headers = kw.headers ? kw.headers : {};
        self.headers['X-Requested-With'] = 'XMLHttpRequest';
        if ('size' in file) {
            self.headers['X-File-Name'] =  file.name;
            self.headers['X-File-Size'] = file.size;
        }
        else {
            self.headers['X-File-Name'] =  file.fileName;
            self.headers['X-File-Size'] = file.fileSize;            
        }
        self.headers['Content-Type'] = 'application/octet-stream';
        if (self.onProgress)
            self.http.upload.onprogress = self.onProgress;
        self.callSuccess = uploadSuccess;
        return postAjax(file);
    };
    function rpc(url, name, kw) {
        if (!self.http) return false;
        self.url = url;
        self.onSuccess = kw.onSuccess ? kw.onSuccess : null;
        self.onError = kw.onError ? kw.onError : null;
        self.timeout = kw.timeout ? kw.timeout : 0;
        self.headers = kw.headers ? kw.headers : {};
        self.headers['Content-Type'] = 'application/octet-stream';
            self.id = Math.round(Math.random()*1000+1);
        var obj =  {
            param: kw.param ? kw.param : null,
            id: self.id,
            method: name,
            jsonrpc: '2.0'
        };
        if (reddevil.console)
            console.log('rpc send:',url,name,obj);
        self.callSuccess = rpcSuccess;
        return postAjax(JSON.stringify(obj));
    };
    function postAjax(data){
        if (!self.http) return false;
        self.http.open('post', self.url, true);
        for (var i in self.headers) {
            self.http.setRequestHeader(i, self.headers[i]);
        }
        self.http.onreadystatechange = ajaxResponse;
        self.http.send(data);
        if (self.timeout)
            self.timeoutid = setTimeout(onTimeout, self.timeout);
        return true;
    };
    function ajaxResponse(){
        if (self.http.readyState == 4) {
            if (self.http.status == 200) {  
                if (self.timeoutid) clearTimeout(self.timeoutid);
                self.callSuccess(self.http.responseText);
            }
            else if(self.onError)
                self.onError('ajax_error');
        }
    };
    function onTimeout(){
        self.http.abort();
        self.timeoutid = null;
        if (reddevil.console) console.log('Error: Ajax timeout');
		if (self.onError) self.onError(reddevil._('ajax_timeout'));   
    }
    function uploadSuccess(data){
        try {
            var json = JSON.parse(data);
            if (json.result == "OK") {
                self.onSuccess(json);
            }
            else 
                throw new Error("No result in json.");
        }
        catch(err) {
            if (reddevil.console) console.log('Error:', err);
			if (self.onError) self.onError(reddevil._('ajax_application'));
        }   
    };
    function rpcSuccess(data){
        try {
            var json = JSON.parse(data);
            if (reddevil.console) console.log('rpc receive:', json)
            if ('error' in json) {
                if (reddevil.console) console.log('RPC Error:', json.error);
                if (self.onError) self.onError(reddevil._('ajax_application'));
                return;
            }
            if (json.id != self.id) {
                if (reddevil.console) console.log('RPC Error: wrong id');
                if (self.onError) self.onError(reddevil._('ajax_application'));
                return;
            }
            if (!'result' in json) {
                if (reddevil.console) console.log('RPC Warning: missing result');
                json.result = null;
            }
        }
        catch(err) {
            if (reddevil.console) console.log('RPC not successful:', err);
			console.log('Error self:', self);
			if (self.onError) self.onError(reddevil._('ajax_application'));
			return;
        }
		try {
            if (self.onSuccess) self.onSuccess(json.result);
		}
		catch(err) {
            if (reddevil.console)
				console.log('RPC onSuccess call back unsuccessfull:', err);
			if (self.onError)
				self.onError(reddevil._('ajax_application'));		
		}
    };
    reddevil.json.prototype = {
		uploadFile: uploadFile,
		rpc: rpc,
		init: init
	};
})();

// tabcontainer: a contaniner class for multiple tabs

reddevil.tabpages = function(el, url){ return this.init(this, el, url);};
(function(){
	var self;
	function init(obj, el, url) {
		self = obj;
		self.el = el;
		self.tc = $(el) // the tabcontainer
		self.tc.tabs({add:handleAdd, select:handleSelect});
		self.url = url 
		self.ta = []; // tabsarray
		self.initf = false;
		return self;
	};
	function add(name, kw) {	
		self.ta.push({
			caching: kw.caching || false,
			disabled: kw.disabled || false,
			method: kw.method,
			name: name,
			caption: kw.caption,
			loaded: false,
			param: kw.param || {}
		});
		var ix = self.ta.length - 1;
		var tab = self.ta[ix];
		self.tc.tabs('add', self.el + '_' + tab.name, tab.caption);
		return ix
	};
	function handleAdd(ev, ui) {
		var tab = self.ta[ui.index];
		tab.panel = $(ui.panel).append('Loading ...');
		if (ui.index == 0) load(ui.index);
	};
	function handleSelect(ev, ui) {
		var tab = self.ta[ui.index];
		if (!tab.loaded) {
			load(ui.index);
			return;
		}
		if (!tab.caching && tab.initf) {
            try {
                tab.initf(tab.jr);
            }
            catch(err) {
                reddevil.message.error(
                    'Application Error!. Inform the webmaster');
                if (reddevil.console)
                    console.log('Error calling initf javascript in tab ', 
                        tab.name, '. Error', err);
            }
		}
	};
	function load(ix) {
		var tab = self.ta[ix];
		self.loadix = ix; // remember which tab is being loaded
		rq = new reddevil.json();
		rq.rpc(self.url, tab.method, {
			onSuccess: loaded,
			onError: loadfailed,
			param: tab.param,
			timeout: 10000
		});
	}
	function loaded(rs){
        var f, tab = self.ta[self.loadix];
		tab.jr = {};
		for (f in rs) {
			if (f == 'htmlfile' || f =='jsfile') continue;
			tab.jr[f] = rs[f];
		}
		tab.panel.addClass('ui-helper-reset').html(rs.htmlfile);
		if ('jsfile' in rs) {
            try {
                f = new Function(rs.jsfile);
            }
            catch(err) {
                reddevil.message.error(
                    'Application Error!. Inform the webmaster');
                if (reddevil.console)
                    console.log('Cannot parse javascript in tab ', 
                        tab.name, '. Error', err);
            }
            try {
                tab.initf = f();
            }
            catch(err) {
                reddevil.message.error(
                    'Application Error!. Inform the webmaster');
                if (reddevil.console)
                    console.log('Cannot run javascript in tab ', 
                        tab.name, '. Error', err);
            }
            try {
                tab.initf(tab.jr);
            }
            catch(err) {
                reddevil.message.error(
                    'Application Error!. Inform the webmaster');
                if (reddevil.console)
                    console.log('Error calling initf javascript in tab ', 
                        tab.name, '. Error', err);
            }
		}
		tab.loaded = true;
	}
	function loadfailed() {
		reddevil.message.error('Application Error! Inform the webmaster',
			10000);
	}
	function checkload(name, kw) {
		var ix;
		$.each(self.ta, function(i, t){
			if (t.name == name)  {
				self.tc.tabs('remove',i);
				self.ta.splice(i,1);
				return false;
			}
		});
		ix = self.add(name, kw)
		self.tc.tabs('select', ix);
	};
	reddevil.tabpages.prototype = {
		init: init,
		add: add,
		checkload: checkload,
	};
	
})();

// message: a namespace with 2 messaging functions: show, error

reddevil.message = {};
(function(){
	var rf;
    function info(msg, period) {
		var el = $('#infomsg'), timeoutid;
        $('#infotxt').text(msg)
        el.show();
        if (timeoutid) clearTimeout(timeoutid);
        if (period>0) timeoutid = setTimeout(function(){
			el.hide();
		}, period);
		el.click(function(){ el.hide(); });
    };
    function error(msg){
		var el = $('#errmsg');
        $('#errtxt').text(msg);
        el.show();
        el.click(function(){ el.hide(); });
    };
	function confirm(msg, f) {
		var el = $('#dialmsg')
		rf = f;
		if (el.length == 0) {
			$('body').append('<div id="dialmsg"><p id="dialmsg_text">' +
				'<span class="ui-icon ui-icon-alert" style="float:left;' +
				'margin:0 7px 20px 0;>');
			el = $('#dialmsg').attr('title','Confirmation')
				.dialog({autoOpen: false, modal: true});
		}
		$('#dialmsg_text').text(msg);
		el.dialog('option', 'buttons', [{
			text: 'OK', click: confirmOK}, {
			text: 'Cancel', click: confirmCancel}]);
		el.dialog('open');
	}
	function confirmOK() {
		$(this).dialog('close');
		rf(true);
	}
	function confirmCancel() {
		$(this).dialog('close');
		rf(false);
	}
    reddevil.message = {
		info: info,
		error: error,
		confirm: confirm
	}
})();

