


CloseLabelText = '\u0417\u0430\u043a\u0440\u044b\u0442\u044c';

attachEventListener = function(target, eventType, functionRef, capture) {

    if (typeof(functionRef)== 'string') {
        functionRef=eval(functionRef);
    }

    if (typeof target.addEventListener != "undefined") {
        target.addEventListener(eventType, functionRef, capture);
    } else if (typeof target.attachEvent != "undefined"){
        target.attachEvent("on" + eventType, functionRef);
    } else {
        eventType = "on" + eventType;
        if(typeof target[eventType] == "function") {
            var oldListener = target[eventType];
            target[eventType] = function(){
                oldListener();
                return functionRef();
            };
        } else {
            target[eventType] = functionRef;
        }

    }
};

$C = function( tagName, id, parent ) {
    var el = document.createElement(tagName);
    if( id != null ) {
        el.id = id;
    }
    if( parent != null ) {
        parent.appendChild(el);
    }
    return el;
};

$CC = function(tagName, id, parent, styles, properties, initFunction ) {
    var el = document.createElement(tagName);
    if( id != null ) {
        el.id = id;
    }
    applyStyles( el, styles );
    applyProperties( el, properties );
    if( initFunction != undefined && initFunction != null ) {
        initFunction.call( el, el );
    }
    if( parent != null ) {
        parent.appendChild(el);
    }
    return el;
};

$DC = function( element ) {
    try {
        if( element != undefined && element != null && element.parent != undefined && element.parent != null ) {
            element.parent.removeChild( element );
        }
    } catch(e) {
    }
};

$dispose = function( element ) {
    $DC(element);
    recursiveCleaner(element);
};

applyStyles = function( element, values ) {
    if( element != undefined && element != null && values != undefined && values != null ) {
        for( var p in values ) {
            element.style[p] = values[p];
        }
    }
};

applyProperties = function( element, values ) {
    if( element != undefined && element != null && values != undefined && values != null ) {
        for( var p in values ) {
            element[p] = values[p];
        }
    }
};

function RectangularArea( x, y, width, height ) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

RectangularArea.prototype.getWidth = function() {
    return this.width;
};

RectangularArea.prototype.getHeight = function() {
    return this.height;
};

RectangularArea.prototype.applyToElement = function( el ) {
    applyStyles( el, {
        left: (this.x.toString() + 'px') ,
        top: (this.y.toString() + 'px'),
        width: (this.width.toString() + 'px'),
        height: (this.height.toString() + 'px')
    });
};

var JSWindowType = 0;
var JSWindowTypeClose = 1;
var JSWindowTypeYesNo = 2;
var JSWindowTypeOKCancel = 2;


function JSWindow() {
    this.rootDiv = null;
    this.bgdiv = null;
    this.clientDiv = null;
    this.bodyDiv = null;
    this.titleDiv = null;
    this.caption = 'untitled window';
    this.position = new RectangularArea(100, 100, 400, 200);
    this.modal = true;
    this.zOrder = 100;

    this.onshow = null;
    this.onhide = null;
    this.onok = null;
    this.oncancel = null;
    this.type = JSWindowType;
}

JSWindow.prototype.setType = function(type) {
    // NOTE: should be used before construct!
    this.type = type;
};

JSWindow.prototype.construct = function() {
    if( this.position == null ) {
        throw 'Position is null, fail to construct window';
    }
    if( this.modal ) {
        this.bgdiv = $CC( 'div', null, document.body, {
            display: 'none',
            position: 'fixed',
            margin: '0px 0px 0px 0px',
            padding: '0px 0px 0px 0px',
            border: 'none',
            left: '0px',
            top: '0px',
            width: '100%',
            height: '100%',
            zIndex: (this.zOrder)
        });
    }
    var t = this;

    this.rootDiv = $CC( 'div', null, document.body, {
        display: 'none',
        position: 'absolute',
        zIndex: (this.zOrder + 1),
        //        border: '1px solid red',
        overflow: 'hidden'
    }, null, function(rootDiv) {
        rootDiv.className = 'windowRoot';
        t.titleDiv = $CC( 'div', null, this, null, {
            className: 'windowCaption'
        });
        t.clientDiv = $CC( 'div', null, this, {
            marginTop: '2px',
            marginLeft: '2px',
            marginRight: '2px',
            marginBottom: '2px',
            padding: '0 0 0 0 ',
            //            width: (t.position.getWidth() - 8) + 'px',
            //            height: ((t.position.getHeight() - 22 - 4) + 'px'),
            overflow: 'auto'
        }, {
            className: 'windowClient'
        }, function(client) {
            t.bodyDiv = $CC( 'div', null, this, {
                marginLeft: '2px',
                marginRight: '2px'
            //                border: '1px solid orange'
            });
        });

        switch( t.type ) {
            case JSWindowType:
            case JSWindowTypeClose:
                $CC( 'button', null, this, {
                    height: '20px',
                    textAlign: 'right'
                }, {
                    value: CloseLabelText,
                    innerHTML: CloseLabelText,
                    onclick: function() {
                        t.closeWindow();
                        if( t.onok ) {
                            t.onok();
                        }
                    }
                });
                break;
            case JSWindowTypeYesNo:
                $CC( 'button', null, this, {
                    height: '20px',
                    textAlign: 'right'
                }, {
                    value: 'Yes',
                    innerHTML: 'Yes',
                    onclick: function() {
                        t.closeWindow();
                        if( t.onok ) {
                            t.onok();
                        }
                    }
                });
                $CC( 'button', null, this, {
                    height: '20px',
                    textAlign: 'right'
                }, {
                    value: 'No',
                    innerHTML: 'No',
                    onclick: function() {
                        t.closeWindow();
                        if( t.oncancel ) {
                            t.oncancel();
                        }
                    }
                });
                break;
            case JSWindowTypeOKCancel:
                $CC( 'button', null, this, {
                    height: '20px',
                    textAlign: 'right'
                }, {
                    value: 'Yes',
                    innerHTML: 'Yes',
                    onclick: function() {
                        t.closeWindow();
                        if( t.onok ) {
                            t.onok();
                        }
                    }
                });
                $CC( 'button', null, this, {
                    height: '20px',
                    textAlign: 'right'
                }, {
                    value: 'No',
                    innerHTML: 'No',
                    onclick: function() {
                        t.closeWindow();
                        if( t.oncancel ) {
                            t.oncancel();
                        }
                    }
                });
                break;
            default:
                // TODO: error handling
                t.dispose();
                break;
        }
    });

    if( this.position != null ) {
        this.position.applyToElement(this.rootDiv);
    }
    this.setCaption(null);
};

JSWindow.prototype.dispose = function() {
    try {
        recursiveCleaner(this.bgdiv);
        recursiveCleaner(this.bodyDiv);
        recursiveCleaner(this.clientDiv);
        recursiveCleaner(this.rootDiv);
        recursiveCleaner(this.titleDiv);

        $DC(this.rootDiv);
        $DC(this.bgdiv);
    } finally {
        this.clientDiv = null;
        this.titleDiv = null;
        this.rootDiv = null;
        this.bgdiv = null;
        this.bodyDiv = null;
    }
};

JSWindow.prototype.setCaption = function( caption ) {
    if( caption != undefined && caption != null ) {
        this.caption = caption;
    }
    if( this.titleDiv != null ) {
        if( this.titleDiv.firstChild != null ) {
            this.titleDiv.replaceChild( document.createTextNode(this.caption), this.titleDiv.firstChild );
        } else {
            this.titleDiv.appendChild( document.createTextNode(this.caption) );
        }
    }
};

JSWindow.prototype.setOnShow = function( onshow ) {
    this.onshow = onshow;
};

JSWindow.prototype.setOnHide = function( onhide ) {
    this.onhide = onhide;
};

JSWindow.prototype.setOnOk = function( onok ) {
    this.onok = onok;
};

JSWindow.prototype.setOnCancel = function( oncancel ) {
    this.oncancel = oncancel;
};

JSWindow.prototype.resize = function( rectangle ) {
    if( rectangle != undefined && rectangle != null ) {
        this.position  = rectangle;
    }
    if( this.position == null ) {
        throw 'window cant be resized, because position is null-pointer';
    }
    if( this.rootDiv != null ) {
        applyStyles( this.rootDiv, {
            left: (document.documentElement.scrollLeft + this.position.x) + 'px',
            top: (document.documentElement.scrollTop + this.position.y) + 'px',
            width: this.position.getWidth() + 'px',
            height: this.position.getHeight() + 'px'
        });
        applyStyles( this.clientDiv, {
            width: (this.position.getWidth() - 8) + 'px',
            height: ((this.position.getHeight() - 45 - 4) + 'px')
        });
    }
};

JSWindow.prototype.showWindow = function() {
    if( this.rootDiv == null ) {
        this.construct();
    }
    this.setCaption();
    this.resize();
    if( this.rootDiv != null ) {
        this.rootDiv.style.display = 'block';
    }
    if( this.bgdiv != null ) {
        this.bgdiv.style.display = 'block';
    }
    if( this.onshow != null ) {
        this.onshow.call( this );
    }
    var t = this;
    //alert( document.body.add)
    window.onscroll = function(e) {
        t.resize(null);
    };

//    attachEventListener(window, 'onscroll', function(e) {
//        alert( 'zz' );
//        t.resize(null);
//    }, false);

};

JSWindow.prototype.getBody = function() {
    if( this.rootDiv == null ) {
        this.construct();
    }
    return this.bodyDiv;
};

JSWindow.prototype.closeWindow = function() {
    if( this.rootDiv != null ) {
        if( this.bgdiv != null ) {
            this.bgdiv.style.display = 'none';
        }
        this.rootDiv.style.display = 'none';
        if( this.onhide ) {
            this.onhide.call(this, this);
        }
    }
};

// NOTE: rewrite these methods if prototype is not used in project

JSWindow.prototype.loadFromURL = function( url, showWindowAfterLoad, script, onload ) {
    this.loadScript(script);
    var t = this;
    new Ajax.Request( prefix + url, {
        onComplete : function( transport ) {
            t.getBody().innerHTML = transport.responseText;
            if( showWindowAfterLoad ) {
                t.showWindow();
            }
            if( onload ) {
                onload.call(t, transport);
            }
        }
    });
};

JSWindow.prototype.loadScript = function( script ) {
    var r = new Ajax.Request( prefix + script, {
        onComplete : function( transport ) {
            if( r.success() ) {
            //return eval( transport.responseText );
            }
            return null;
        }
    });
};

