/**
 *
 * JavaScript-ClassLib
 * 
 * 
 * Gives Object-Orientated Class behaviour
 * with inheritance functionality
 * 
 * -------------------------------------
 * Example:
 * Person = CF.Lib.Object.extend({
 * 
 * 		name: '',
 * 
 * 		construct: function () {
 * 			this.name = 'default person';
 * 		},
 * 
 * 		sayHello: function () {
 * 			alert('hello i am ' +this.name);
 * 			this.inherited();
 * 		}
 * 
 * 
 * });
 * 
 * Peter = Person.create('Peter');
 * 
 * 
 *
 * Author: Joachim Schweisgut, j.schweisgut@triplesense.de
 *
 *
 */





CF = {};

CF.Lib = {};
CF.Lib.Prototypes = [];


CF.Lib.Object = {

    __id: 0,
    __parentclass: null,

    

    construct: function () {
    },

    
    
    isInstanceOf: function (classname) {
        return false;
    },
    
    getClassName: function () {
        return '';
    },
    

    create: function (a,b,c,d,e,f,g,h,i,j) {
        var result = {};

        var list = [this];
        while (list[0].__parentclass) 
            list.unshift(list[0].__parentclass);

        for (var i in list) 
            for (var key in list[i]) 
                result[key] = list[i][key];
        
        result.__parentclass = list[list.length-1];
        result.__id = null;
        result.create = null;

        result.construct(a,b,c,d,e,f,g,h,i,j);
        return result;
    },




    extend: function (obj) {
        for (var i in obj) {
            if (typeof obj[i]=='function') {
                obj[i].__classref = obj;
                obj[i].__fktname = i;
            }
        }
        obj.__id = CF.Lib.Prototypes.length;
        obj.__parentclass = this;
        
        obj.extend = this.extend;
        obj.create = this.create;
        obj.inherited = this.inherited;
        
        CF.Lib.Prototypes.push(obj);
        return obj;
    },


    

    inherited: function (a,b,c,d,e,f,g,h,i,j) {
        var fktname = this.inherited.caller.__fktname;
        var parentclass = this.inherited.caller.__classref;
        while (parentclass = parentclass.__parentclass) {
            if (parentclass[fktname]) {
                var fkt = 'super_'+fktname+'_'+parentclass.__id;
                if (!this[fkt])
                    this[fkt] = parentclass[fktname];
                return this[fkt](a,b,c,d,e,f,g,h,i,j);
            }
        }
    }



}


/* add first prototype class manually */
CF.Lib.Prototypes.push(CF.Lib.Object);







/* 
 * Basic Objects 
 * 
 * 
 */
CF.Lib.Notifier = CF.Lib.Object.extend({

    items: null,
    owner: null,


    construct: function (owner) {
        this.inherited();
        this.owner = owner;
        this.items = [];
    },



    clear: function () {
        while (this.items.length) {
            var obj = this.items.shift();
            obj.listener = null;
            obj.handler = null;
            obj.event = null;
            delete obj;
        }
    },


    find: function (listener,event,handler) {
        for (var i=0;i<this.items.length;i++) {
            var item = this.items[i];
            if ((item.listener==listener) && (!handler || (item.handler==handler)) && (!event || (item.event==event)))
                return item;
        }
    },



    add: function (listener,event,handler){
        if (!this.find(listener,handler,event)) {
            var obj = {
                'listener': listener,
                'handler': handler,
                'event': event
            };
            this.items.push(obj);
        }
    },

    remove: function (listener){
        var list = new Array();
        while (this.items.length) {
            var item = this.items.shift();
            if (item.listener==listener) {
                item.listener = null;
                delete item;
            } else
                list.push(item);
        }
        this.items = list;
    },



    notify: function (event,a,b,c,d,e,f,g){
        for (var i=0;i<this.items.length;i++) {
            if (this.items[i].event == event)
                if (this.items[i].listener [this.items[i].handler])
                    this.items[i].listener [this.items[i].handler](this.owner,event,a,b,c,d,e,f,g);
        }
    }

});







CF.Lib.EventObject = CF.Lib.Object.extend({
    
    notifier: null,
    handleEvents: true,

    
    
    addListener: function (listener,event,handler) {
        if (!this.notifier)
            this.notifier = CF.Lib.Notifier.create(this);
        this.notifier.add(listener,event,handler);
    },
    
    
    notify: function (type,a,b,c,d,e,f,g) {
        this.handleEvent(type,a,b,c,d,e,f,g);
    },

    handleEvent: function (type,a,b,c,d,e,f,g) {
        if (this.handleEvents) {

            var result = false;
            if (this ['handle_'+type])
                result = this ['handle_'+type](a,b,c,d,e,f,g);

            if (!result && this.notifier)
                this.notifier.notify(type,a,b,c,d,e,f,g);
        }
    },
    
    assign: function (data) {
        throw "can't assign data";
    }



});




CF.Lib.Control = CF.Lib.EventObject.extend({
    
    element: null,
	
    construct: function (elem) {
        this.inherited();
        this.element = (elem)?elem:null;
    },
    
    getElement: function() {
        return this.element;
    }


});










CF.fkt = CF.Lib.Object.extend({
	
    cancelEvent: function (event) {
        event.cancelBubble = true;
        if (event.stopPropagation)
            event.stopPropagation();        
    },
	
    inRange: function (num,min,max) {
        return (min<=num<=max)?true:false;
    },
	
	
    ltrim: function (value) {
        var re = /\s*((\S+\s*)*)/;
        return value.replace(re, "$1");
    },

    rtrim: function (value) {
        var re = /((\s*\S+)*)\s*/;
        return value.replace(re, "$1");
    },

    trim: function (value) {
        return CF.fkt.ltrim(CF.fkt.rtrim(value));
    },
	
    isset: function (value) {
        return (CF.fkt.isNull(value))?false:true;
    },
	
    isNull: function (value) {
        try {
            return ((value==undefined) || (typeof(value)=='undefined'))?true:false;
        }catch(e){};
        return false;
    }
	
	
	
		
});








