/*global DARTY */
DARTY = DARTY || {};
DARTY.util = DARTY.util || {};
// <dependencies checking>
(function(){// Depends on Init.js, Mixin.js
    var from = "DARTY.util.Log";
    var libs = ["DARTY.util.Init","DARTY.util.Mixin"];    
	if (DARTY && DARTY.util && DARTY.util.required) {    
        DARTY.util.required(libs, from);
    }
    else {
      if(DARTY && DARTY.DEBUG) {	
        alert("Missing library : DARTY.util.Init in " + from);
      }  
    }
})();
// </dependencies checking>
DARTY.util.Log = function(){
	// ------------ utility extension 
	String.prototype.nextline = function() {
		return(this + "\n");
	};
	
	String.prototype.add = function(str) {
		return(this + str);
	};
    // ------- private variables ---------------
	var CONST = {
		TYPE:{
			ERROR: 'error',
			INFO: 'info',
			WARN : 'warn',
			DEBUG: 'debug'
		}
	}
	var mixin = DARTY.util.Mixin;	
	var logs;	
	var serialized = "";
	var info;
	// ------- private methods -----------------
	var serialize;
	var info;
	var warn;
	var debug;
	var display;
	var getSerializedLogs;
	var getSerializedLogsHtml;
	var writeLogsInDocument;
	var getLogsObject;
	// -----------------------------------------
    
	logs = {};
	logs[CONST.TYPE.INFO] = [];
	logs[CONST.TYPE.WARN] = [];
	logs[CONST.TYPE.ERROR] = [];
	logs[CONST.TYPE.DEBUG] = [];
		
	serialize = function(o){	
	    var result ="";
		if (o) {
            result = result.nextline().add(mixin.serialize.apply(o));
			if (o && o.object) {
				result = result.nextline().add("object : ").nextline().add("{").nextline().add(mixin.serialize.apply(o.object)).add("}").nextline();
			}
		}
		serialized = serialized.nextline().add(result);
		return result;
	}; 
    
    info = function(o){ // o : {message:'error message', description: 'error description'} 
        if (o) {
			o.type = CONST.TYPE.INFO;
			logs[o.type].push(o);
			display(o);
		}
    };
	
    warn = function(o){ // o : {message:'error message', description: 'error description'} 
        if (o) {
			o.type = CONST.TYPE.WARN;
			logs.warn.push(o);
			display(o);
		}
    };
    var error = function(o){ // o : {message:'error message', description: 'error description'} 
        if (o) {
			o.type = CONST.TYPE.ERROR;
			logs.error.push(o);
			display(o);
		}
    };
	
    debug = function(o){ // o : {message:'error message', description: 'error description'} 
        if (o) {
			o.type = CONST.TYPE.DEBUG;
			logs.debug.push(o);
			display(o);
		}
    };
	
    display = function(o){
        var console = console; var body = document.body;
        var commentContent = serialize(o);
        var comment = document.createComment(commentContent);
        if (body) {
            body.appendChild(comment);
        }
    };
	
	getSerializedLogs = function(){
			return(serialized);
	};
	
	getSerializedLogsHtml = function() {
		return "<xmp>" + getSerializedLogs() + "</xmp>";
	}
	
	writeLogsInDocument = function() {
		document.write(getSerializedLogsHtml());
	};
	
	getLogsObject = function() {
		return logs;
	}; 
	
    // ------ public properties & methods
    return {
        info: info,
        warn: warn,
        error: error,
        debug: debug,
		getSerializedLogs: getSerializedLogs,
		getSerializedLogsHtml: getSerializedLogs,
		writeLogsInDocument: writeLogsInDocument,
		getLogsObject : getLogsObject
	};
}();