// create namespace for plugins
Ext.namespace('Itk.plugins');
 
/**
 * @author mpetelin
 */

Itk.plugins.State = function(config) {
    Ext.apply(this, config);
};
 
// plugin code
Ext.extend(Itk.plugins.State, Ext.util.Observable, {
    init:function(panel) {
		Ext.apply(panel, {

	 		stateEvents: ["collapse","expand"],
			getState:function() {
				return {collapsed:this.collapsed};
			}	
		})
    } // end of function init
    
}); // end of extend

Ext.util.lz77 = {
	    encode: function(s){
	    	var dict = {};
	        var data = (s + "").split("");
	        var out = [];
	        var currChar;
	        var phrase = data[0];
	        var code = 256;
	        for (var i=1; i<data.length; i++) {
	            currChar=data[i];
	            if (dict[phrase + currChar] != null) {
	                phrase += currChar;
	            }
	            else {
	                out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
	                dict[phrase + currChar] = code;
	                code++;
	                phrase=currChar;
	            }
	        }
	        out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
	        for (var i=0; i<out.length; i++) {
	            out[i] = String.fromCharCode(out[i]);
	        }
	        
	        return out.join("");

	    },
	    decode: function(s){
	    	var dict = {};
	    	var data = (s + "").split("");
	    	var currChar = data[0];
	    	var oldPhrase = currChar;
	    	var out = [currChar];
	    	var code = 256;
	    	var phrase;
	    	for (var i=1; i<data.length; i++) {
		    	var currCode = data[i].charCodeAt(0);
		    	if (currCode < 256) {
		    		phrase = data[i];
		    	}else {
		    		phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
		    	}
		    	out.push(phrase);
		    	currChar = phrase.charAt(0);
		    	dict[code] = oldPhrase + currChar;
		    	code++;
		    	oldPhrase = phrase;
	    	}
	    	return out.join("");

	    }

}

Ext.util.base64 = {

	    base64s : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
	    
	    encode: function(decStr){
	        if (typeof btoa === 'function') {
	             return btoa(decStr);            
	        }
	        var base64s = this.base64s;
	        var bits;
	        var dual;
	        var i = 0;
	        var encOut = "";
	        while(decStr.length >= i + 3){
	            bits = (decStr.charCodeAt(i++) & 0xff) <<16 | (decStr.charCodeAt(i++) & 0xff) <<8 | decStr.charCodeAt(i++) & 0xff;
	            encOut += base64s.charAt((bits & 0x00fc0000) >>18) + base64s.charAt((bits & 0x0003f000) >>12) + base64s.charAt((bits & 0x00000fc0) >> 6) + base64s.charAt((bits & 0x0000003f));
	        }
	        if(decStr.length -i > 0 && decStr.length -i < 3){
	            dual = Boolean(decStr.length -i -1);
	            bits = ((decStr.charCodeAt(i++) & 0xff) <<16) |    (dual ? (decStr.charCodeAt(i) & 0xff) <<8 : 0);
	            encOut += base64s.charAt((bits & 0x00fc0000) >>18) + base64s.charAt((bits & 0x0003f000) >>12) + (dual ? base64s.charAt((bits & 0x00000fc0) >>6) : '=') + '=';
	        }
	        return(encOut);
	    },
	    
	    decode: function(encStr){
	        if (typeof atob === 'function') {
	            return atob(encStr); 
	        }
	        var base64s = this.base64s;        
	        var bits;
	        var decOut = "";
	        var i = 0;
	        for(; i<encStr.length; i += 4){
	            bits = (base64s.indexOf(encStr.charAt(i)) & 0xff) <<18 | (base64s.indexOf(encStr.charAt(i +1)) & 0xff) <<12 | (base64s.indexOf(encStr.charAt(i +2)) & 0xff) << 6 | base64s.indexOf(encStr.charAt(i +3)) & 0xff;
	            decOut += String.fromCharCode((bits & 0xff0000) >>16, (bits & 0xff00) >>8, bits & 0xff);
	        }
	        if(encStr.charCodeAt(i -2) == 61){
	            return(decOut.substring(0, decOut.length -2));
	        }
	        else if(encStr.charCodeAt(i -1) == 61){
	            return(decOut.substring(0, decOut.length -1));
	        }
	        else {
	            return(decOut);
	        }
	    }

	};  

Ext.namespace("Itk.plugins.toast");
Itk.plugins.toast.show = function(title, format, format_args, icon, delay, auto_destroy, apply_to){
	var xtpl = format || "<span class=\"message-title\">{title}</span><span class=\"message-body\">{body}</span>";
	var message = new Ext.XTemplate(xtpl);
	message = message.apply(format_args);
	var toast = new Ext.ux.Notification({
		bodyCssClass: 'toast-notification',
		title: title,
		html: message,
		autoDestroy: auto_destroy || true,
		hideDelay: delay || 1500,
		iconCls: icon || 'x-icon-information'
	}); 
	toast.show(apply_to || document);
};

Itk.plugins.toast.error = function(head, message, apply_to){
	Itk.plugins.toast.show(
					'Error', 
					null,
					{title: head, body: message}, 'x-icon-error', 4000, true, apply_to
					);
};

Itk.plugins.toast.notify = function(head, message, apply_to){
	Itk.plugins.toast.show(
					'Information', 
					null,
					{title: head, body: message}, 'x-icon-information', 4000, true, apply_to
					);
};

Ext.namespace("Itk.plugins.explorer");
Itk.plugins.explorer.nodeContextMenu = function (node, event){
 	var menu = node.ctmenu;
	if(!node.attributes.context_menu_actions && !this.default_context_menu) return false;
	if(!menu){
	    menu = new Ext.menu.Menu({id: 'node-' + node.id + '-ctmenu', xtype: 'menu'});
		menu.show(node.ui.getEl());
		var add_menu_entry = function(item, idx, all){
			if(item.type == 'separator'){
				this.addSeparator();
			}else{
				var action_template = new Ext.XTemplate(item.action);
    			var item_func = new Function("", action_template.applyTemplate(this._current_node.attributes));
    			this.addItem({id: this._current_node.id + '-' + item.id, iconCls: item.icon, handler: item_func, text: item.name});
			}
		}
		
		if(this.default_context_menu){
			menu._current_node = node;
			var nodeType = "";
			for(var type in this.default_context_menu){
				if(node.id.match('^'+type)){
					Ext.iterate(this.default_context_menu[type], add_menu_entry, menu);
				}
			}
		}
		if(node.attributes.context_menu_actions){
			menu._current_node = node;
			Ext.iterate(node.attributes.context_menu_actions, add_menu_entry, menu);
		}
		node.ctmenu = menu;
	}
	menu.showAt(event.getXY());
};

Itk.plugins.explorer.insertBelow = function(target, node) {
	target.parentNode.appendChild(node);
	target.parentNode.replaceChild(node, target);
	node.parentNode.insertBefore(target, node);
};

Itk.plugins.explorer.appendAsLastCMS = function(target, node) {
	node.rendered = false;
	node.ui.rendered = false;
	if(target.hasChildNodes()){
		var first_project_child = target.findChildBy(function(){
										if(this.id.match('^projekt_')) {
											return true;
										}
										return false;
										});
		target.appendChild(node);
		if(first_project_child != null){
			target.insertBefore(node, first_project_child);
		}
	}else{
		target.appendChild(node);
	}
	target.expand(false,false);
	target.ownerTree.saveState();
};
 
Ext.namespace("Itk.plugins.startseite");
Itk.plugins.startseite.contextMenu = function (record, menu, event, scope) {
	if(record.length) record = record[0];
	if(record.data.url.length != 0 && event.type != "contextmenu"){
		window.location = record.data.url;
		return;
	}
	event.preventDefault();
	if(record.data.actions){
		var menu_add = function(action_key, action, record){
			var events_add = function(event, func, object){
			var my_func = new Function("", func);
				this.on(event, my_func, record);
			};
			var item = this.add({text: action.text});
			Ext.iterate(action.events, events_add, item);
		};
		Ext.iterate(record.data.actions, menu_add, menu);
		if(menu.items.length){
			x = event.browserEvent.clientX;
			y = event.browserEvent.clientY;
			menu.showAt([x, y]);
		}
	}
	
	return false;
};

