////////////////////////////////////////////////////////////////////////////
// class DebugLog extends WndBorder
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// constructor
////////////////////////////////////////////////////////////////////////////
DebugLog = function()
{
    this.subclass = WndBorder;
    this.subclass();

    this.rowCount = 0;
    
    this.className = "DebugLog";
}
DebugLog.prototype = new WndBorder;
DebugLog.instance = null;
DebugLog.limit = 100;
DebugLog.keyHook = {
    keyCodes: [
        //d  e   b  u   g   l   o   g
        100,101,98,117,103,108,111,103
        //100, 100, 100 // "ddd" - tmp
    ],
    current: -1,
    timerId: 0
};

////////////////////////////////////////////////////////////////////////////
// _create
////////////////////////////////////////////////////////////////////////////
DebugLog.prototype._create = function(flags)
{
    this.subclass = WndBorder.prototype.create;
    this.subclass(document.body, "Debug Window",
        WND_FLAGS_HIDDEN | WND_FLAGS_CAPTION | WND_FLAGS_BORDER | WND_FLAGS_MOVE | WND_FLAGS_VRESIZE | WND_FLAGS_HRESIZE);
    this.element.className += " debug_wnd";
    
    this.elLog = AP.createElement("div");
    this.childArea().appendChild(this.elLog);
    this.elLog.className = "ap debug_log";

    this.appendButtons([
        {
            text: "<span style=\"cursor: pointer;\">_<span>",
            id: IDMINIMIZE
        },
        {
            text: "<span style=\"cursor: pointer;\">X<span>",
            id: IDCLOSE
        }
    ]);
    var x = parseInt(AP.getCookie("Debug_xPos", "20"));
    x = Math.max(0, (isNaN(x)?20:x));
    var y = parseInt(AP.getCookie("Debug_yPos", "20"));
    y = Math.max(0, (isNaN(y)?20:y));
    var cx = parseInt(AP.getCookie("Debug_cxPos", "500"));
    cx = Math.min(1000, Math.max(100, isNaN(cx)?500:cx));
    var cy = parseInt(AP.getCookie("Debug_cyPos", "200"));
    cy = Math.min(1000, Math.max(100, isNaN(cy)?200:cy));
    this.setPosition({ x: x, y: y, cx: cx, cy: cy });
    
    this.addNotifyHandler( [DebugLog._onBtnClick, this] );
    AP.addEvent(document.body, "keypress", DebugLog.onDocKeyPress);

    if ( parseInt(AP.getCookie("Debug_show", 0)) == 1 )
    {
        this._show(true, false);
    }
}

////////////////////////////////////////////////////////////////////////////
// _write
////////////////////////////////////////////////////////////////////////////
DebugLog.prototype._write = function(row_class, text)
{
    var rowElement = AP.createElement("div", this._logElement(), "debug_log_row " + row_class);
    var dateElement = AP.createElement("span", rowElement, "debug_log_date");
    dateElement.innerHTML = DebugLog.makeTime() + ": ";
    var textElement = AP.createElement("span", rowElement, "debug_log_text");
    textElement.innerHTML = text;
    this.rowCount += 1;

    // limit log size
    if ( this.rowCount > DebugLog.limit )
    {
        DebugLog.clear( this.rowCount - DebugLog.limit );
    }
    
    this._logElement().scrollTop = this._logElement().scrollHeight;
}

////////////////////////////////////////////////////////////////////////////
// setPosition
////////////////////////////////////////////////////////////////////////////
DebugLog.prototype.setPosition = function(pos)
{
    this.subclass = WndBorder.prototype.setPosition;
    this.subclass(pos);
    AP.setCookie("Debug_xPos", pos.x, 365);
    AP.setCookie("Debug_yPos", pos.y, 365);
    AP.setCookie("Debug_cxPos", pos.cx, 365);
    AP.setCookie("Debug_cyPos", pos.cy, 365);
}

////////////////////////////////////////////////////////////////////////////
// _show
////////////////////////////////////////////////////////////////////////////
DebugLog.prototype._show = function(show, store)
{
    if ( show )
    {
        this.show();
    }else
    {
        this.hide();
    }
    if ( store )
    {
        AP.setCookie("Debug_show", show ? 1 : 0, 365);
    }
}

////////////////////////////////////////////////////////////////////////////
// _logElement
////////////////////////////////////////////////////////////////////////////
DebugLog.prototype._logElement = function()
{
    return this.elLog;
}

////////////////////////////////////////////////////////////////////////////
// restricts
DebugLog.prototype.assignChild = function(childEl) { return null; }
// restricts
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
// makeTime
////////////////////////////////////////////////////////////////////////////
DebugLog.makeTime = function()
{
    var objDate = new Date();
    
    var mm = objDate.getMonth() + 1; // !!!
    if ( mm < 10 ) mm = "0" + mm;
    var dd = objDate.getDate();
    if ( dd < 10 ) dd = "0" + dd;
    var yyyy = objDate.getFullYear();
    var h = objDate.getHours();
    if ( h < 10 ) h = "0" + h;
    var min = objDate.getMinutes();
    if ( min < 10 ) min = "0" + min;
    var sec = objDate.getSeconds();
    if ( sec < 10 ) sec = "0" + sec;
    var ms = objDate.getMilliseconds();
    if ( ms < 100 ) ms = "0" + ms;
    if ( ms < 10 ) ms = "0" + ms;

    return  mm + "/" +
            dd + "/" +
            yyyy+ " " +
            h + ":" +
            min + ":" +
            sec + "." +
            ms;
}

////////////////////////////////////////////////////////////////////////////
// _onBtnClick
////////////////////////////////////////////////////////////////////////////
DebugLog._onBtnClick = function(param)
{
    var pThis = param.subscriber;
    if ( pThis != DebugLog.instance )
        return 0;
    
    if ( param.code == DLGN_BTN_CLICKED )
    {
        if ( param.param == IDMINIMIZE )
        {
            DebugLog.instance._show(false, false);
        }else if ( param.param == IDCLOSE )
        {
            DebugLog.clear();
            DebugLog.write("<font color=green>cleared</font>");
            DebugLog.instance._show(false, true);
        }
    }
    
    return 0;
}

////////////////////////////////////////////////////////////////////////////
// _createIfNotExist
////////////////////////////////////////////////////////////////////////////
DebugLog._createIfNotExist = function(str)
{
    if ( !DebugLog.instance )
    {
        DebugLog.instance = new DebugLog();
        DebugLog.instance._create();
    }
}

////////////////////////////////////////////////////////////////////////////
// onDocKeyPress
////////////////////////////////////////////////////////////////////////////
DebugLog.onDocKeyPress = function(ev)
{
    ev || (ev = window.event);
    var keyCode = ev.charCode || ev.keyCode;
    
    if ( keyCode == DebugLog.keyHook.keyCodes[DebugLog.keyHook.current + 1] )
    {
        if ( DebugLog.keyHook.timerId )
        {
            clearTimeout(DebugLog.keyHook.timerId);
            DebugLog.keyHook.timerId = 0;
        }
        DebugLog.keyHook.current++;
        if ( DebugLog.keyHook.current == (DebugLog.keyHook.keyCodes.length - 1) )
        {
            DebugLog.keyHook.current = -1;
            DebugLog.instance._show(true, true);
        }else
        {
            DebugLog.keyHook.timerId = setTimeout("DebugLog.keyHook.current = -1;", 1000);
        }
    }
    
    return true;
}

////////////////////////////////////////////////////////////////////////////
// getInstance
////////////////////////////////////////////////////////////////////////////
DebugLog.getInstance = function(obj)
{
    for ( var o = obj; o && !(o.instance && DebugLog.prototype.isPrototypeOf(o.instance)); o = o.parentNode );
    return (o ? o.instance : null);
}

////////////////////////////////////////////////////////////////////////////
// write
////////////////////////////////////////////////////////////////////////////
DebugLog.write = function(str)
{
    DebugLog._createIfNotExist();
    DebugLog._createIfNotExist();

    var resultString = "";
    for (var loop = 0; loop < arguments.length; loop++ )
    {
        if (loop)
        {
            resultString += " - ";
        }
        resultString += arguments[loop];
    }

    DebugLog.instance._write("", resultString);
}

////////////////////////////////////////////////////////////////////////////
// writeErr
////////////////////////////////////////////////////////////////////////////
DebugLog.writeErr = function(str)
{
    DebugLog._createIfNotExist();
    DebugLog._createIfNotExist();

    var resultString = "";
    for (var loop = 0; loop < arguments.length; loop++ )
    {
        if (loop)
        {
            resultString += " - ";
        }
        resultString += arguments[loop];
    }

    DebugLog.instance._write("error", resultString);
    DebugLog.instance._show(true, false);
}

////////////////////////////////////////////////////////////////////////////
// clear
////////////////////////////////////////////////////////////////////////////
DebugLog.clear = function(nCount)
{
    DebugLog._createIfNotExist();
    nCount = AP.is_set(nCount, -1);
    for (
        var spFirst = null;
        nCount && ( spFirst = AP.firstChild(DebugLog.instance._logElement()) );
        nCount--
    )
    {
        spFirst.parentNode.removeChild(spFirst);
        DebugLog.instance.rowCount--;
    }
}
