var Helper = Class.create();
Helper.prototype = {

    initialize: function() {
        this.mouseover = new Array();
        this.mouseout  = new Array();
        this.mousemove = new Array();
        this.mouseclick = new Array();
        this.content = new Array();

        this._id = 0;
        this._currentShowedId = null;
        this._width = 0;
        this._height = 0;
        this._idPrefix = 'hlp_';
        this._position = {x: 0, y: 0};

        this._helperElement = $('previo-helper');
        this._helperIframeElement = $('previo-helper-iframe');
    },

    /**
     * Spusteni instance Helperu
     *
     * @param String content text, ktery se ma zobrazit v Helperu
     * @param Array properties nastaveni "obsluhy" (handleru) Helperu
     *      width - sirka handleru
     *      height - vyska handleru
     *      style - css styly
     *      element - jaky element ma byt pouzit (defaultne "SPAN")
     *      className - css class (defaultne "phelper_default")
     *      text - text, ktery ma byt zobrazen v handleru (defaultne "?")
     */
    start: function(content, properties) {
        this._id++;
        var handlerId = this._idPrefix + this._id;

        var style = '';
        style += (properties) ? ((properties.width) ? 'width:' + properties.width + ';' : '') : '';
        style += (properties) ? ((properties.height) ? 'height:' + properties.height + ';' : '') : '';
        style += (properties) ? ((properties.style) ? properties.style + ';' : '') : '';
        if (style != '') {
            style = ' style="' + style + '"';
        }

        var element = (properties) ? (properties.element || 'span') : 'span';
        var className = (properties) ? (properties.className || 'phelper_default') : 'phelper_default';
        var text = (properties) ? (properties.text || '?') : '?';

        setTimeout(this._setObservers.bind(this, handlerId, content, null), 0);
        return ' <' + element + ' id="' + handlerId + '" class="' +
            ((text == '?') ? 'phelper ' : '') + className + '"' + style + '>' +
            text + '</' + element + '> ';
    },

    /**
     * Spusteni instance Helperu v pripade, kdy mame element bez IDcka
     * @param Element element element, na kterem chceme Helper spustit
     * @param String content text, ktery chceme mit zobrazen v helperu po najeti mysi na element
     * @return int id helperu
     */
    runAsObserver: function (element, content) {
    	this._id++;
        var handlerId = this._idPrefix + this._id;

        setTimeout(this._setObservers.bind(this, handlerId, content, element), 0);

        return handlerId;
    },

    /**
     * Nastavuje posluchace pro zobrazovani a pohyb Helperu
     *
     * @param int id id handleru
     * @param String content text, ktery se ma zobrazit v Helperu
     */
    _setObservers: function(id, content, element) {
        if ($(id) || element) {
        	var obElement = (element) ? element : id;
            this.mouseover[id] = Event.observe(obElement, 'mouseover', this.show.bindAsEventListener(this, id));
            this.mouseout[id]  = Event.observe(obElement, 'mouseout', this.hide.bindAsEventListener(this));
            this.mousemove[id] = Event.observe(obElement, 'mousemove', this._setHelperPosition.bindAsEventListener(this));
            this.mouseclick[id]= Event.observe(obElement, 'mousedown', this.hide.bindAsEventListener(this));
            this.content[id] = content;
        }
    },

    /**
     * Ziska aktualni id handleru (i s prefixem)
     */
    getCurrentHandlerId: function() {
        return this._idPrefix + this._id;
    },

    /**
     * Zmeni text v Helperu
     *
     * @param int id id handleru
     * @param String content text, ktery se ma zobrazit v Helperu
     */
    changeHelperContent: function(id, content) {
        if ($(id)) {
            this.content[id] = content;
            if (id == this._currentShowedId) {
            	this._helperElement.innerHTML = content;
            }
        }
    },

    /**
     * Odstrani posluchace pro zobrazovani a pohyb Helperu
     *
     * @param int id id handleru
     */
    _removeObservers: function(id) {
        if ($(id)) {
            Event.stopObserving(id, 'mouseover', this.mouseover[id]);
            Event.stopObserving(id, 'mouseout', this.mouseout[id]);
            Event.stopObserving(id, 'mousemove', this.mousemove[id]);
            Event.stopObserving(id, 'mousedown', this.mouseclick[id]);
        }
    },

    /**
     * Nastavuje pozici Helperu
     */
    _setHelperPosition: function(e) {

    	var position = {
    			x: e.clientX,
    			y: e.clientY
    	};


        position.x += (document.all) ? document.documentElement.scrollLeft : window.pageXOffset;
        position.y += (document.all) ? document.documentElement.scrollTop : window.pageYOffset;

        // ak su hodnoty diametralne odlisne alebo vacsie / rovne 0, pouzi stare hodnoty z this
        if (position.x <= 0) {position.x = this._position.x;}
        if (position.y <= 0) {position.y = this._position.y;}

        position.x += 10;
        position.y += 15;

        if (position.x >= document.documentElement.offsetWidth - this._width) {
            position.x -= this._width - (document.documentElement.offsetWidth - position.x) + 2;
        }

        if (position.y >= document.documentElement.offsetHeight - this._height) {
            position.y -= this._helperElement.offsetHeight + 20;
        }

		// ulozime stare hodnoty do this._position
        this._position = position;

        this._helperElement.style.left = (this._position.x - 20) + 'px';
        this._helperElement.style.top = this._position.y + 'px';

        this._helperIframeElement.style.left = (this._position.x - 20) + 'px';
        this._helperIframeElement.style.top = this._position.y + 'px';
    },

    /**
     * Zobrazi Helper
     *
     * @param String content text, ktery se ma zobrazit v Helperu
     */
    show: function(e, id) {
        this._currentShowedId = id;

        // event se tu musi predavat dalsim funkcim jako kopie toho objektu,
        // jinak to pada v MSIE7, ktery neumi event predavat (nepreda kopii ale odkaz, ktery uz pak muze byt neplatny)
        var eventCopy = {};
        eventCopy.clientX = e.clientX;
        eventCopy.clientY = e.clientY;

        setTimeout(this.setHelperSize.bind(this, eventCopy), 0);

        this._helperElement.innerHTML = this.content[id];

        this._helperIframeElement.height = this._helperElement.clientHeight - 1; // cimrmanova konstanta 1, aby to vyšlo v IE 6
        this._helperIframeElement.width = this._helperElement.clientWidth;

        // na zkousku zobrazeni az na posledni chvili
        this._helperIframeElement.style.display = 'block';
        this._helperElement.style.display = 'block';
    },

    setHelperSize: function(e) {
        this._width = this._helperElement.clientWidth;
    	this._height = this._helperElement.clientHeight;

    	// obcas ma element jeste nastaveno display:none (prodleva aktualizace DOMu?),
    	// tak nakecame jinou sirku
    	if (this._width == 0) {
    		this._width = 310;
    	}

    	this._setHelperPosition(e);
    },

    /**
     * Skryje Helper
     */
    hide: function(e) {
    	this._currentShowedId = null;
        this._helperElement.style.display = 'none';
        this._helperIframeElement.style.display = 'none';
    }
};

