Ajax.Responders.register({
    onCreate: function(transport) {
        if ($('spinner') && Ajax.activeRequestCount > 0)
            Element.show('spinner', {duration:0.5,queue:'end'});
    },
    onComplete: function(transport) {
        if ($('spinner') && Ajax.activeRequestCount == 0)
            Element.hide('spinner', {duration:0.5,queue:'end'});
    }
});

var AsariWeb = Class.create();

AsariWeb.globals = {};

AsariWeb.errorOccured = false;

AsariWeb.Utils = {
    navigate : function(url) {
        document.location = url;
    }
}

AsariWeb.AjaxRequest = Class.create(Ajax.Request, {
    handleErrors: function() {
        if (AsariWeb.errorOccured)
            return;
        AsariWeb.errorOccured = true;
        alert("Wystąpił błąd w aplikacji. Zostaniesz wylogowany i przekierowany do strony logowania. Spróbuj zalogować się ponownie." +
              "W celu uzyskania pomocy skontaktuj się z firmą Protoss.")
        //document.location.href = '/userBase/logout';
    },

    handleUnauthorizedAccess: function() {
        if (AsariWeb.errorOccured)
            return;
        AsariWeb.errorOccured = true;
        alert("Nie jesteś aktualnie zalogowany. Zostaniesz  przekierowany do strony logowania. Aby uzyskać dostęp do tej strony zaloguj się ponownie." +
              "W celu uzyskania pomocy skontaktuj się z firmą Protoss.")
        document.location.href = '/';
    },

    initialize: function($super, url, options) {
        var object = this;
        this.options = $H({
            evalScripts:true,
            on403:function() {
                object.handleUnauthorizedAccess();
            },
            on404:function() {
                object.handleErrors();
            },
            on500:function() {
                object.handleErrors();
            },
            on302:function() {
                object.handleErrors();
            },
            onFailure:function() {
                object.handleErrors();
            },
            onComplete:function(response) {
                if ((response.status < 200 || response.status > 299) && response.status != 0) {
                    object.handleErrors();
                }
            }
        });
        this.options.update(options || {});
        var timestamp = new Date().getTime();
        if (url.indexOf("?") > -1)
            url = url + '&t=' + timestamp;
        else
            url = url + '?t=' + timestamp;
        $super(url, this.options.toObject());
    }
});


AsariWeb.AjaxUpdater = Class.create(AsariWeb.AjaxRequest, {

    initialize: function($super, id, url, options) {
        this.options = $H({
            onSuccess: function(transport) {
                $(id).update(transport.responseText);
            }
        });
        $super(url, this.options.toObject());
    }
});

AsariWeb.IE6SelectZindexHack = {
    isIE6 : function () {
        return Prototype.Browser.IE && navigator.appVersion.indexOf("MSIE 6.0") != -1;
    },
    showSelects : function() {
        if (!this.isIE6())
            return;
        $(document.body).select("select").each(function(select) {
            select.show();
        });
    },
    hideSelects : function() {
        if (!this.isIE6())
            return;
        (document.body).select("select").each(function(select) {
            select.hide();
        })
    }
}


AsariWeb.FloatUtils = {
    convertToServerFloatFormat : function(float) {
        return float.toString().replace('.', ',');
    },
    convertToBrowserFloatFormat : function(string) {
        return parseFloat(string.replace(',', '.'));
    },
    roundNumber: function(number) {
        return Math.round(number * 100) / 100;
    }

};

AsariWeb.CalculatePriceUtils = {
    calculatePrice : function(area, pricePerUnit) {
        return AsariWeb.FloatUtils.roundNumber(area * pricePerUnit)
    },
    calculatePricePerUnit : function(area, price) {
        return AsariWeb.FloatUtils.roundNumber(price / area)
    },
    pricesAreCorrect : function(area, price, pricePerUnit) {
        return (Math.round(AsariWeb.FloatUtils.roundNumber(area * pricePerUnit)) == Math.round(price));
    }
}

AsariWeb.CalculateAddOnFactorUtils = {

    calculateBruttoTotalArea:function(area, addOnFactor) {
        return AsariWeb.FloatUtils.roundNumber(area * (1 + addOnFactor / 100));
    },

    calculateAddOnFactor:function(area, bruttoTotalArea) {
        return AsariWeb.FloatUtils.roundNumber((bruttoTotalArea / area - 1) * 100);
    },

    factorIsCorrect : function(area, adOnFactor, bruttoTotalArea) {
        return this.calculateBruttoTotalArea(area, adOnFactor) == bruttoTotalArea;
    }
}


AsariWeb.Widgets = {}

AsariWeb.Widgets.Dropdown = Class.create({

    initialize: function(id, classHover, options) {
        var object = this;

        var options = options || {selectFirst:true};

        $(id).observe('mouseover', function() {
            var el = $(id);
            el.addClassName(classHover);
            var div = $$("#" + id + " div")[0];
            var ul = $$("#" + id + " ul")[0];
            var observer = function(event) {
                var pointerX = event.pointerX();
                var pointerY = event.pointerY();
                if (!(object.pointerInDiv(pointerX, pointerY, div)) && !(object.pointerInDiv(pointerX, pointerY, ul))) {
                    $(id).removeClassName(classHover);
                    $$('#' + id + ' ul')[0].hide();
                    Event.stopObserving(document, 'mousemove', observer);
                }
            };
            Event.observe(document, 'mousemove', observer);
            ul.setStyle({
                position: 'absolute',
                top: div.positionedOffset()[0] + div.getHeight() + 'px',
                left: '0px'
            });
            ul.show();
        });

        if (options.selectFirst) {
            $$('#' + id + ' li:first-child').each(function(li) {
                li.addClassName("selected");
            });
        }
    },

    pointerInDiv :function(pointerX, pointerY, div) {
        return   pointerX + 2 >= div.cumulativeOffset()[0] &&
                 pointerX - 2 <= div.cumulativeOffset()[0] + div.getWidth() &&
                 pointerY + 2 >= div.cumulativeOffset()[1] &&
                 pointerY - 2 <= div.cumulativeOffset()[1] + div.getHeight()
    }
});

AsariWeb.Widgets.Tabs = Class.create({
    initialize: function(tabs) {
        $A(tabs).each(function(tab) {
            $(tab.button).observe('mouseover', function() {
                $(tab.button).addClassName(tab.cssClassOver);
            })

            $(tab.button).observe('mouseout', function() {
                $(tab.button).removeClassName(tab.cssClassOver);
            })

            $(tab.button).observe('click', function() {
                $A(tabs).each(function(otherTab) {
                    if (otherTab == tab)
                        return;
                    $(otherTab.button).removeClassName(otherTab.cssClassSelected);
                    $(otherTab.button).removeClassName(otherTab.cssClassOver);
                    $(otherTab.div).hide();
                });
                $(tab.button).removeClassName(tab.cssClassOver);
                $(tab.button).addClassName(tab.cssClassSelected);
                $(tab.div).show();
                //TODO refactoring
                if (globalMap) {
                    globalMap.checkResize();
                    globalMap.returnToSavedPosition()
                }
            })
        });
    }
});


AsariWeb.Widgets.ShowHidePanel = Class.create({
    button:null,
    panel:null,
    showText:'',
    hideText:'',

    initialize: function(buttonId, panelId, showText, hideText, show) {
        this.button = $(buttonId);
        this.panel = $(panelId);
        this.showText = showText;
        this.hideText = hideText;
        this.button.observe('click', this.toogleVisibility.bind(this));
        if (show)
            this.toogleVisibility();
    },

    toogleVisibility : function() {
        this.panel.toggle();
        this.button.update(this.panel.visible() ? this.hideText : this.showText);
    }

});

AsariWeb.Widgets.ScrollableGallery = Class.create({
    centerDiv:null,
    slideshowDiv:null,
    backwardButtonDiv:null,
    forwardButtonDiv:null,
    thumbnailHeight:0,
    imageCount:0,
    totalOffset:0,

    initialize: function(wrapperId, thumbnailHeight) {
        var innerDivs = $$("#" + wrapperId + ">div>div");
        this.backwardButtonDiv = innerDivs[0];
        this.centerDiv = innerDivs[1];
        this.slideshowDiv = this.centerDiv.select("div")[0];
        this.forwardButtonDiv = innerDivs[2];
        this.thumbnailHeight = thumbnailHeight;
        this.backwardButtonDiv.observe('click', this.scrollBackward.bind(this));
        this.forwardButtonDiv.observe('click', this.scrollForward.bind(this));
        this.imageCount = this.slideshowDiv.select("img").length;
    },

    scrollBackward : function() {
        if (this.isFirstVisable())
            return;
        new Effect.Move(this.slideshowDiv, { x: 0, y: this.thumbnailHeight, mode: 'relative' });
        this.totalOffset += this.thumbnailHeight;
    },

    scrollForward : function() {
        if (this.isLastVisable())
            return;
        new Effect.Move(this.slideshowDiv, { x: 0, y: -this.thumbnailHeight, mode: 'relative' });
        this.totalOffset -= this.thumbnailHeight;
    },

    isFirstVisable : function() {
        return this.totalOffset == 0;
    },

    isLastVisable : function() {
        return (this.centerDiv.getHeight() - this.totalOffset) >= (this.thumbnailHeight * this.imageCount)
    }

});

AsariWeb.Widgets.ContextMenu = Class.create({
    menu:null,
    menuUl:null,
    items:null,

    initialize: function() {
        this.items = [];
    },

    setId:function(menuId) {
        this.menu = $(menuId);
        this.menuUl = this.menu.select('ul')[0];
    },

    addItem : function(item) {
        this.items.push(item);
    },

    reload: function(selection) {
        this.menuUl.innerHTML = '';
        var object = this;
        $A(object.items).each(function(item) {
            var failedCondition = item.detectFalseCondition(selection);
            var li;
            if (failedCondition)
                li = object.buildDisabledItemNode(selection, item, failedCondition.hint);
            else
                li = object.buildActiveItemNode(selection, item);
            object.menuUl.appendChild(li);
        });
    },

    buildActiveItemNode: function(selection, item) {
        return Builder.node('li', {}, [
            Builder.node('a', {
                href:item.getLink(selection)
            }, item.text)
        ]);
    },

    buildDisabledItemNode: function(selection, item, hint) {
        return Builder.node('li', [
            Builder.node('div', {
                className:'disabled',
                onmouseover:'$(this).addClassName("disabledOver");$(this).select("div")[0].show();',
                onmouseout:'$(this).removeClassName("disabledOver");$(this).select("div")[0].hide();'
            }, [
                Builder.node('span', item.text),
                Builder.node('div', {className:'hintLeft', style:'display:none'}, [
                    Builder.node('div', {className:'hint-pointer'}),
                    Builder.node('span', hint)
                ])
            ])
        ]);
    }
});

AsariWeb.Widgets.ContextMenuItem = Class.create({
    text:'',
    link: function(state) {
        return 'javascript:void(0);'
    },
    conditions:[],
    //do nadpisania w kalsie dziedziczącej
    predefinedConditions: {},
    prepareSelection : function(selection) {
        return selection;
    },

    initialize: function(options) {
        this.text = options.text || this.text;
        this.conditions = options.conditions || this.conditions;
        this.link = options.link || this.link;
        var object = this;
        this.conditions = $A(options.conditions).collect(function(condition) {
            if (typeof(condition) == 'string') {
                return object.predefinedConditions[condition]
            }
            return condition
        });
    },

    detectFalseCondition : function(selection) {
        var object = this;
        return $A(this.conditions).detect(function(condition) {
            return ! condition.check(object.prepareSelection(selection));
        });
    },

    getLink: function(selection) {
        return this.link(this.prepareSelection(selection))
    },

    copySingleMarkedToSelected : function(selection, selectedKey, markedListKey) {
        if (! selection[selectedKey] && selection[markedListKey] && selection[markedListKey].length == 1) {
            selection[selectedKey] = selection[markedListKey][0];
        }
    },

    copySelectedToMarked: function(selection, selectedKey, markedListKey) {
        if (selection[selectedKey]) {
            selection[markedListKey] = [selection[selectedKey]]
        }
    }
});

AsariWeb.TableWidgets = {}

AsariWeb.TableWidgets.SelectableRow = Class.create({

    initialize: function(rowId, onclick) {
        $$('#' + rowId + ' td').each(function(td) {
            if (td.hasClassName('cart'))
                return;
            td.observe('mouseover', function() {
                if (!$(td.parentNode).hasClassName('selected'))
                    $(td.parentNode).addClassName('over');
            });
            td.observe('mouseout', function(row) {
                $(td.parentNode).removeClassName('over');
            });
            td.observe('click', onclick);
        })
    }
});

AsariWeb.TableWidgets.DoubleSelectableRow = Class.create({

    initialize: function(rowId, onclick) {
        $$('#' + rowId + ' td').each(function(td) {
            var thisRow = $(td.parentNode);
            var nextRow = $(td.parentNode).nextSiblings()[0]

            if (td.hasClassName('cart'))
                return;
            td.observe('mouseover', function() {
                if (!thisRow.hasClassName('selected'))
                    thisRow.addClassName('over');
                nextRow.addClassName('over');
            });
            td.observe('mouseout', function(row) {
                thisRow.removeClassName('over');
                nextRow.removeClassName('over');
            });


            td.observe('click', onclick);
        })
    }
});

AsariWeb.TableWidgets.DoubleSelectableRowDescription = Class.create({

    initialize: function(rowId, onclick) {
        $$('#' + rowId + ' td').each(function(td) {
            var thisRow = $(td.parentNode);
            var prevRow = $(td.parentNode).previousSiblings()[0]

            if (td.hasClassName('cart'))
                return;
            td.observe('mouseover', function() {
                if (!thisRow.hasClassName('selected'))
                    thisRow.addClassName('over');
                prevRow.addClassName('over');
            });
            td.observe('mouseout', function(row) {
                thisRow.removeClassName('over');
                prevRow.removeClassName('over');
            });


            td.observe('click', onclick);
        })
    }
});


AsariWeb.TableWidgets.MarkCheckbox = Class.create({
    initialize: function(checkboxId, checkboxAllId, onCheckedTrue, onChackedFalse) {
        $(checkboxId).observe('click', function(event) {
            var input = event.element();
            var parentTr = $(input.parentNode.parentNode);
            if (input.checked) {
                parentTr.addClassName('selected');
                onCheckedTrue();
            } else {
                parentTr.removeClassName('selected');
                onChackedFalse();
                $(checkboxAllId).checked = false;
            }
        });
    }
});

AsariWeb.TableWidgets.CartSwitch = Class.create({
    initialize: function(switchId, counterId, addUrl, removeUrl) {
        $(switchId).observe('click', function(event) {
            var indicator = event.element();
            if (indicator.hasClassName("starSelected")) {
                indicator.removeClassName("starSelected");
                new AsariWeb.AjaxRequest(removeUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                    }
                });

            } else {
                indicator.addClassName("starSelected");
                new AsariWeb.AjaxRequest(addUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                    }
                });

            }
        });
    }
});

AsariWeb.TableWidgets.MarkAllCheckbox = Class.create({
    initialize: function(checkboxId, tableId, onMarked, onUnMarked) {

        var input = $(checkboxId);
        input.observe('click', function() {
            if (input.checked) {
                var marked = []
                $$('table#' + tableId + ' tbody tr').each(function(row) {
                    marked.push(row.selectionMetadata);
                    row.addClassName('selected');
                    row.select('input')[0].checked = true;
                });
                onMarked(marked);
            } else {
                $$('table#' + tableId + ' tbody tr').each(function(row) {
                    row.removeClassName('selected');
                    row.select('input')[0].checked = false;
                });
                onUnMarked();
            }
        });
    }
});


AsariWeb.TableWidgets.CartCheckbox = Class.create({
    initialize: function(checkboxId, counterId, addUrl, removeUrl, menu) {
        $(checkboxId).observe('click', function(event) {
            var input = event.element();
            var parentTr = $(input.parentNode.parentNode);
            var selectedListing = listingStateHolder.state.get('selected');
            var selectedSeeker = seekerStateHolder.state.get('selected');

            if (input.checked) {
                parentTr.addClassName('selected');
                new AsariWeb.AjaxRequest(addUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            } else {
                parentTr.removeClassName('selected');
                new AsariWeb.AjaxRequest(removeUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            }
        });
    }
});


AsariWeb.TableWidgets.CartDetailsCheckbox = Class.create({
    initialize: function(checkboxId, counterId, addUrl, removeUrl, menu) {
        $(checkboxId).observe('click', function(event) {
            var input = event.element();
            if (input.checked) {
                new AsariWeb.AjaxRequest(addUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            } else {
                new AsariWeb.AjaxRequest(removeUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            }
        });
    }
});

AsariWeb.TableWidgets.DoubleCartCheckbox = Class.create({
    initialize: function(checkboxId, counterId, addUrl, removeUrl, menu) {
        $(checkboxId).observe('click', function(event) {
            var input = event.element();
            var parentTr = $(input.parentNode.parentNode);
            var nextTr = $(input.parentNode.parentNode).nextSiblings()[0];

            var selectedListing = listingStateHolder.state.get('selected');
            var selectedSeeker = seekerStateHolder.state.get('selected');

            if (input.checked) {
                parentTr.addClassName('selected');
                nextTr.addClassName('selected');
                new AsariWeb.AjaxRequest(addUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            } else {
                parentTr.removeClassName('selected');
                nextTr.removeClassName('selected');
                new AsariWeb.AjaxRequest(removeUrl, {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            }
        });
    }
});

AsariWeb.TableWidgets.AddAllCheckbox = Class.create({
    initialize: function(checkboxId, counterId, addUrl, removeUrl, menu, table) {

        $(checkboxId).observe('click', function(event) {
            var selectedListing = listingStateHolder.state.get('selected');
            var selectedSeeker = seekerStateHolder.state.get('selected');
            var query = "&" + listingStateHolder.state.get('query');
            var table = $(this.parentNode.parentNode.parentNode.parentNode);
            var rows = table.select("tr");
            var checboxes = table.select("tr input");

            if (this.checked) {
                rows.invoke('addClassName', ['selected'])
                checboxes.each(function(it) {
                    it.checked = true
                });
                new AsariWeb.AjaxRequest((addUrl + query), {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker: selectedSeeker
                        });
                    }
                });
            } else {
                rows.invoke('removeClassName', ['selected'])
                checboxes.each(function(it) {
                    it.checked = false
                });
                new AsariWeb.AjaxRequest((removeUrl + query), {
                    onSuccess: function(transport) {
                        if ($(counterId))
                            $(counterId).update(transport.responseText);
                        menu.reload({
                            selectedListing : selectedListing,
                            selectedSeeker:selectedSeeker
                        });
                    }
                });
            }
        });
    }
});


AsariWeb.Widgets.SwitchableForm = Class.create({
    sections : [],
    formId:null,

    initialize: function(sections, formId) {
        this.sections = sections;
        this.formId = formId;
        var object = this;
        $A(sections).each(function(section) {
            if (!$(section.radio)) return
            $(section.radio).observe('click', function(radio) {
                object.switchTo(section.sectionId)
            });

        });
    },

    switchTo : function(sectionId) {
        var section = $A(this.sections).find(function(section) {
            return section.sectionId == sectionId
        });
        $(section.radio).checked = true;
        $(this.formId).action = section.url;
        $A(this.sections).each(function(otherSection) {
            var inputs = $$("#" + otherSection.sectionId + " input[type!=radio]");
            if (otherSection.sectionId == section.sectionId) {
                inputs.each(function (input) {
                    input.enable()
                })
            } else {
                inputs.each(function (input) {
                    input.disable()
                })
            }
        });
    }
});


AsariWeb.Widgets.ExportOrderRow = Class.create({
    exportId:null,
    row:null,
    checkboxes:null,
    select:null,
    url:null,
    rowPrice:null,
    netPriceId:null,
    totalPriceId:null,
    dateDiv:null,
    dateSpan:null,
    priceTotaIds:null,

    initialize: function(exportId, url, netPrice, totalPrice, priceTotaIds) {
        var object = this;
        this.row = $(exportId);
        this.exportId = exportId;
        this.url = url;
        this.checkboxes = this.row.select('input[type=checkbox]');
        this.select = this.row.select('select')[0];
        this.rowPrice = this.row.select('td:last-child')[0];
        this.dateDiv = this.row.select('div[name=nextEndOfSubscription]')[0];
        this.dateSpan = this.row.select('span[name=nextEndOfSubscription]')[0];
        this.netPriceId = netPrice;
        this.totalPriceId = totalPrice;
        this.priceTotaIds = priceTotaIds;
        this.checkboxes.each(function(checkbox) {
            checkbox.observe('change', function() {
                object.checkboxes.each(function(otherCheckbox) {
                    if (otherCheckbox != checkbox)
                        otherCheckbox.checked = false;
                    checkbox.checked = true;
                });
                object.getPrice();
            });
        });
        this.select.observe('change', object.getPrice.bind(this))
    },

    getPrice:function() {
        var object = this;
        var selectedCheckbox = this.checkboxes.find(function(checkbox) {
            return checkbox.checked
        });
        if (selectedCheckbox)
            new AsariWeb.AjaxRequest(this.url, {
                method:'get',
                parameters:{
                    'exportId':this.exportId,
                    'subscriptionType':selectedCheckbox.name,
                    'numberOfMonths':this.select.value
                },
                onSuccess: function(transport) {
                    object.updatePrices(transport.responseText)
                }});
    },

    updatePrices : function(responseText) {
        var result = responseText.evalJSON();
        this.rowPrice.update(result.price);
        $(this.netPriceId).update(result.netPrice);
        $(this.totalPriceId).update(result.totalPrice);
        this.dateSpan.update(result.nextEndOfSubscription);
        var object = this;
        object.dateDiv.show();
        if (result.readyToBuy) {
            $A(object.priceTotaIds).each(function(id) {
                $(id).show();
            })
        } else {
            $A(object.priceTotaIds).each(function(id) {
                $(id).hide();
            })
        }
    }
});

AsariWeb.Widgets.SelectAutocomplete = Class.create({
    id:null,
    text:null,
    textInput:null,
    idInput:null,
    listDiv:null,
    placeholderInput:null,
    autocomplete:null,
    search:null,

    initialize: function(idInputId, textInputId, placeholderInputId, url, afterUpdate, defaultParams, search) {
        var obj = this;
        this.idInput = $(idInputId);
        this.textInput = $(textInputId);
        this.id = this.idInput.value;
        this.text = this.textInput.value;
        this.listDiv = Builder.node('div', {className:'sautocomplete'});
        this.placeholderInput = $(placeholderInputId);
        this.textInput.insert({after:this.listDiv});
        this.textInput.value = '';
        this.afterUpdate = afterUpdate;
        this.search = search;
        this.autocomplete = new Ajax.Autocompleter(
                this.textInput,
                this.listDiv,
                url,
        {
            paramName:'keyword',
            frequency:0.2,
            minChars:1,
            parameters:defaultParams,
            afterUpdateElement:function(input, li) {
                obj.setParams(li.id.evalJSON(), li.innerHTML);
                obj.textInput.value = '';
            }
        });
        this.textInput.observe('blur', function() {
            obj.textInput.value = '';
        });
        this.textInput.observe('focus', function() {
            obj.textInput.value = '';
        });

        this.textInput.observe('keypress', function(e) {
            if (e.keyCode == 13) {
                e.stop();
            }
        })

    },

    setParams: function(allParams, text, stopPropagation) {
        stopPropagation = stopPropagation || false;
        this.id = allParams.id;
        this.search = allParams.search;
        this.text = text;
        this.placeholderInput.value = text;
        this.idInput.value = this.id;
        this.afterUpdate(this.id, text, allParams, stopPropagation);
    },

    clear: function() {
        this.textInput.value = '';
        this.idInput.value = '';
        this.listDiv.innerHTML = '';
        this.placeholderInput.value = '';
        this.search = '';
    },

    enable: function() {
        this.textInput.enable();
    },

    disable : function() {
        this.textInput.disable();
    },

    addAjaxQueryParams : function(params) {
        this.autocomplete.options.defaultParams = params;
    }
})


AsariWeb.Widgets.LocationMap = Class.create({

    map:null,
    geocoder:null,
    reversegeocoder:null,
    geoLatInput:null,
    geoLngInput:null,
    marker:null,
    searchInput:null,
    zoomLevel:12,
    hintText:'',
    showHint:true,
    hintPrefix:'np .',
    country: 'Polska',

    initialize: function(
            mapDivId,
            searchInputId,
            searchButtonDivId,
            geoLatInputId,
            geoLngInputId,
            initialLocation,
            setInitialMarker,
            hintText,
            showHint,
            country,
            onNewLocationCallback
            ) {
        obj = this;
        if (!GBrowserIsCompatible())
            return;
        this.map = this.getMap(mapDivId, initialLocation);
        this.geoLatInput = $(geoLatInputId);
        this.geoLngInput = $(geoLngInputId);
        this.reversegeocoder = new GReverseGeocoder(this.map);
        GEvent.addListener(this.reversegeocoder, "load", obj.pointToLocation);
        this.geocoder = new GClientGeocoder();
        this.onNewLocationCallback = onNewLocationCallback;
        if (setInitialMarker)
            this.setMarker(initialLocation);
        this.searchInput = $(searchInputId);
        this.hintText = hintText;
        this.showHint = showHint;
        this.country = country;
        this.setHint()
        $(searchButtonDivId).observe('click', function() {
            obj.queryToPoint(obj.searchInput.value, false);
            return false;
        })
        this.searchInput.observe('keypress', function(e) {
            if (e.keyCode == 13) {
                obj.queryToPoint(obj.searchInput.value, false);
                e.stop();
            }
        })

    },

    hintWithPrefix: function() {
        return  this.hintPrefix + this.hintText;
    },

    setHint: function() {
        if (! this.showHint)
            return;
        var obj = this;
        this.searchInput.value = this.hintWithPrefix();
        this.searchInput.observe('focus', function() {
            if (obj.searchInput.value == obj.hintWithPrefix())
                obj.searchInput.value = '';
        });
        this.searchInput.observe('blur', function() {
            if (obj.searchInput.value == '')
                obj.searchInput.value = obj.hintWithPrefix();
        });
    },

    getMap:function(mapDivId, initialLocation) {
        var obj = this;
        var map = new GMap2(document.getElementById(mapDivId));
        map.addControl(new GSmallMapControl());
        map.addControl(new GScaleControl());
        map.setCenter(initialLocation, this.zoomLevel)
        GEvent.addListener(map, "click", function(overlay, newLatLng) {
            obj.setMarker(newLatLng)
            obj.copyPositionToInputs(newLatLng);
            obj.reversegeocoder.reverseGeocode(newLatLng);
        });
        return map;
    },

    setMarker: function(latLng) {
        obj = this;
        if (!this.marker) {
            this.marker = new GMarker(latLng, {draggable:true});
            this.map.addOverlay(this.marker);
            GEvent.addListener(this.marker, "drag", function(newLatLng) {
                obj.copyPositionToInputs(newLatLng);
            });
            GEvent.addListener(this.marker, "dragend", function() {
                obj.reversegeocoder.reverseGeocode(obj.marker.getLatLng());
            });
        }
        this.marker.setLatLng(latLng);
    },

    copyPositionToInputs:function(latLng) {
        this.geoLatInput.value = AsariWeb.FloatUtils.convertToServerFloatFormat(latLng.lat());
        this.geoLngInput.value = AsariWeb.FloatUtils.convertToServerFloatFormat(latLng.lng());
    },

    queryToPoint: function(query, silentMode) {
        if (query == this.hintWithPrefix())
            query = this.hintText;
        query = this.country + ' ' + query;
        var obj = this;
        obj.geocoder.getLocations(query, function(response) {
            if (!response || response.Status.code != 200) {
                if (! silentMode)
                    alert("Niestety podany adres nie został odnaleziony.");
            } else {
                var place = response.Placemark[0];
                var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                obj.setMarker(point);
                obj.copyPositionToInputs(point);
                obj.map.setCenter(point, obj.zoomlevel);
                if (! silentMode)
                    obj.onNewLocation(place);
            }
        });
    },

    pointToLocation: function(location) {
        obj.onNewLocation(location);
    },

    onNewLocation : function(location) {
        var country = obj.reversegeocoder.getPlacemarkProperty(location, "CountryName");
        var province = obj.reversegeocoder.getPlacemarkProperty(location, "AdministrativeAreaName");
        var locality = obj.reversegeocoder.getPlacemarkProperty(location, "LocalityName");
        var street = obj.reversegeocoder.getPlacemarkProperty(location, "ThoroughfareName");
        var geoLat = location.Point.coordinates[1];
        var geoLng = location.Point.coordinates[0];
        this.onNewLocationCallback(country, province, locality, street, geoLat, geoLng);
    },

    searchAndMark : function(query) {
        this.searchInput.value = query;
        this.queryToPoint(query, true);
    }

});

AsariWeb.SeekerPolishForeignSwitch = Class.create({
    countrySelect:null,
    polishLocationTrs:null,
    foreignLocationTrs:null,
    polandSelectValue:null,
    locationAutocomplete:null,
    streetInput:null,
    foreignLocationInput:null,
    foreignStreetInput:null,

    initialize : function(
            countrySelectId, polishLocationTrs, foreignLocationTrs, polandSelectValue,
            locationAutocompleteKey, streetId,
            foreignLocationId, foreignStreetId) {
        this.countrySelect = $(countrySelectId);
        this.polishLocationTrs = polishLocationTrs;
        this.foreignLocationTrs = foreignLocationTrs;
        this.polandSelectValue = polandSelectValue;
        this.foreignLocationInput = $(foreignLocationId);
        this.foreignStreetInput = $(foreignStreetId);
        this.locationAutocomplete = AsariWeb.globals[locationAutocompleteKey];
        this.streetInput = $(streetId);
        this.countrySelect.observe('change', function(event) {
            this.switchLocation();
        }.bind(this));
        this.switchLocation();
    },


    switchLocation: function () {
        if (this.countrySelect.value == this.polandSelectValue) {
            this.swithToPolishLocation();
        } else {
            this.swithToForeignLocation();
        }
    },

    swithToPolishLocation : function () {
        $A(this.polishLocationTrs).each(function(it) {
            $(it).show();
        });
        $A(this.foreignLocationTrs).each(function(it) {
            $(it).hide();
        });
        this.foreignLocationInput.value = '';
        this.foreignStreetInput.value = '';
    },

    swithToForeignLocation : function () {
        $A(this.polishLocationTrs).each(function(it) {
            $(it).hide();
        });
        $A(this.foreignLocationTrs).each(function(it) {
            $(it).show();
        });
        this.locationAutocomplete.disposeAll();
        this.streetInput.value = '';
        this.foreignLocationInput.focus();
    }

});

AsariWeb.ListingPolishForeignSwitch = Class.create({
    countrySelect:null,
    polishLocationTrs:null,
    foreignLocationTrs:null,
    polandSelectValue:null,
    locationAutocomplete:null,
    streetAutocomplete:null,
    foreignLocationInput:null,
    foreignStreetInput:null,
    mapKey:null,

    initialize : function(
            countrySelectId, polishLocationTrs, foreignLocationTrs, polandSelectValue,
            locationAutocompleteKey, streetAutocompleteKey,
            foreignLocationId, foreignStreetId, mapKey) {
        this.countrySelect = $(countrySelectId);
        this.polishLocationTrs = polishLocationTrs;
        this.foreignLocationTrs = foreignLocationTrs;
        this.polandSelectValue = polandSelectValue;
        this.foreignLocationInput = $(foreignLocationId);
        this.foreignStreetInput = $(foreignStreetId);
        this.locationAutocomplete = AsariWeb.globals[locationAutocompleteKey];
        this.streetAutocomplete = AsariWeb.globals[streetAutocompleteKey];
        this.mapKey = mapKey;
        this.countrySelect.observe('change', function(event) {
            this.switchLocation();
        }.bind(this));
        this.switchLocation();
    },

    switchLocation: function () {
        var map = AsariWeb.globals[this.mapKey];
        if (map) {
            map.country = this.countrySelect[this.countrySelect.selectedIndex].text;
        }
        if (this.countrySelect.value == this.polandSelectValue) {
            this.swithToPolishLocation();
        } else {
            this.swithToForeignLocation();
        }
    },

    swithToPolishLocation : function () {
        $A(this.polishLocationTrs).each(function(it) {
            $(it).show();
        });
        $A(this.foreignLocationTrs).each(function(it) {
            $(it).hide();
        });
        this.foreignLocationInput.value = '';
        this.foreignStreetInput.value = '';
        this.locationAutocomplete.textInput.focus();

    },

    swithToForeignLocation : function () {
        $A(this.polishLocationTrs).each(function(it) {
            $(it).hide();
        });
        $A(this.foreignLocationTrs).each(function(it) {
            $(it).show();
        });
        this.locationAutocomplete.clear();
        this.streetAutocomplete.clear();
        this.foreignLocationInput.focus();
    }

});


AsariWeb.LocationSearchProxy = Class.create({
    map:null,
    locationAutocomplete:null,
    streetAutocomplete:null,
    houseNumberInput:null,
    mapToLocationUrl:null,
    countrySelect:null,
    polandSelectValue:null,
    foreignLocationInput:null,
    foreignStreetInput:null,

    initialize : function(
            mapKey, locationAutocomplete, streetAutocomplete,
            houseNumberInput, mapToLocationUrl,
            countrySelectId,
            polandSelectValue,
            foreignLocationId,
            foreignStreetId) {
        this.mapKey = mapKey;
        this.locationAutocomplete = AsariWeb.globals[locationAutocomplete];
        this.streetAutocomplete = AsariWeb.globals[streetAutocomplete];
        this.houseNumberInput = $(houseNumberInput);
        this.mapToLocationUrl = mapToLocationUrl;
        this.countrySelect = $(countrySelectId);
        this.polandSelectValue = polandSelectValue;
        this.foreignLocationInput = $(foreignLocationId);
        this.foreignStreetInput = $(foreignStreetId);
    },

    isPolandSelected : function() {
        return this.countrySelect.value == this.polandSelectValue;
    },

    locationToMap : function() {
        var queryParams = [];
        if (this.isPolandSelected()) {
            if (!this.locationAutocomplete.search)
                return;
            queryParams.push(this.locationAutocomplete.search)
            queryParams.push(this.streetAutocomplete.search)
            if (this.houseNumberInput) {
                queryParams.push(this.houseNumberInput.value)
            }
        } else {
            if (!this.foreignLocationInput.value)
                return;
            queryParams.push(this.foreignLocationInput.value)
            queryParams.push(this.foreignStreetInput.value)
            if (this.houseNumberInput) {
                queryParams.push(this.houseNumberInput.value)
            }
        }
        var query = $A(queryParams).without(null).without('').join(' ');
        if (query)
            AsariWeb.globals[this.mapKey].searchAndMark(query);
    },


    mapToLocation : function(country, province, locality, street, geoLat, geoLng) {
        if (this.isPolandSelected()) {
            if (this.locationAutocomplete.id)
                return;

            var url = this.mapToLocationUrl;
            var parameters = {}
            if (province)
                parameters.province = province;
            if (locality)
                parameters.locality = locality;
            if (street)
                parameters.street = street;
            if (geoLat)
                parameters.geoLat = AsariWeb.FloatUtils.convertToServerFloatFormat(geoLat);
            if (geoLng)
                parameters.geoLng = AsariWeb.FloatUtils.convertToServerFloatFormat(geoLng);
            var obj = this;
            new AsariWeb.AjaxRequest(url, {
                parameters:parameters,
                onSuccess: function(transport) {
                    var parameters = transport.responseText.evalJSON();
                    if (parameters.location) {
                        obj.locationAutocomplete.setParams(parameters.location, parameters.location.normalizedName, true);
                    }
                    if (parameters.street) {
                        obj.streetAutocomplete.setParams(parameters.street, parameters.street.normalizedName, true);
                    }
                    if (obj.houseNumberInput && parameters.houseNumber) {
                        obj.houseNumberInput.value = parameters.houseNumber;
                        obj.streetAutocomplete.setParams(parameters.street, parameters.street.normalizedName, true);
                    }
                }

            });
        } else {
            if (this.foreignLocationInput.value)
                return;
            this.foreignLocationInput.value = locality;
            this.foreignStreetInput.value = street;
        }
    }
})


AsariWeb.FlashBox = Class.create({
    containerDiv:null,
    boxDiv:null,

    initialize : function(containerDiv, boxDiv) {
        this.containerDiv = $(containerDiv);
        this.boxDiv = $(boxDiv);
    },

    showMessage: function(text) {
        this.boxDiv.className = 'flashBoxMessage'
        this.boxDiv.update(text);
        this.animate();
    },

    showError : function(text) {
        this.boxDiv.className = 'flashBoxError'
        this.boxDiv.update(text);
        this.animate();
    },

    animate : function() {
        Effect.SlideDown(this.containerDiv, { duration: 0.5 ,queue: { position: 'end', scope: 'flashBox' }});
        Effect.SlideUp(this.containerDiv, { duration: 0.5 ,queue: { position: 'end', scope: 'flashBox' }, delay:2.0 });
    }

});

AsariWeb.RequestQueue = Class.create({
    queue :[],
    isRequestInProgress:false,

    initialize : function() {
        new PeriodicalExecuter(this.process.bind(this), 0.2);
    },

    pushRequest: function(url, options) {
        this.queue.push([url,options])
    },

    process: function() {
        if (!this.isRequestInProgress && this.queue.length != 0) {
            this.isRequestInProgress = true;
            var request = this.queue.pop();
            var url = request[0];
            var object = this;
            var options = $H({
                onComplete:function() {
                    object.isRequestInProgress = false;
                }
            }).update(request[1] || {})
            new AsariWeb.AjaxRequest(url, options);
        }
    }
})


AsariWeb.MappingForm = Class.create({

    mappingGroups:null,

    initialize: function() {
        this.mappingGroups = new Array();
    },

    add:function (mapping) {
        this.mappingGroups.push(mapping);
    },

    validate:function() {
        var valid = true;
        this.mappingGroups.each(function(group) {
            group.mappings.each(function(mapping) {
                mapping.hideError();
            });
        });
        this.mappingGroups.each(function(group) {
            valid = group.getSelectedMapping().validate() && valid;
        });
        return valid;
    }

});


AsariWeb.MappingGroup = Class.create({
    mappings : null,

    initialize: function(mappingForm) {
        this.mappings = new Array();
        mappingForm.add(this);
    },

    add:function (mapping) {
        this.mappings.push(mapping);
    },

    selectMapping: function (selectedMapping) {
        this.mappings.each(function(mapping) {
            if (selectedMapping == mapping)
                mapping.enable()
            else
                mapping.disable()
        })
    },

    getSelectedMapping:function() {
        return this.mappings.find(function(mapping) {
            return mapping.radiobutton.checked == true;
        });
    }
})

AsariWeb.Mapping = Class.create({

    radiobutton: null,
    group: null,
    field:null,
    required:null,
    errorField:null,

    initialize: function(field, required, radiobutton, group, errorField) {
        this.radiobutton = $(radiobutton);
        this.group = group;
        this.field = field;
        this.required = required;
        this.errorField = $(errorField);
        this.group.add(this);
        this.radiobutton.observe('change', this.onRadioChange.bind(this))
    },

    validate:function() {
        if (this.isValid())
            return true;
        this.showError();
        return false;
    },

    isValid:function() {
        return false;
    },

    showError: function() {
        this.errorField.show();
    },

    hideError: function() {
        this.errorField.hide();
    },

    enable: function() {
    },

    disable:function() {
    },

    onRadioChange :function() {
        this.group.selectMapping(this);
    }
});

AsariWeb.FixedMapping = Class.create(AsariWeb.Mapping, {
    input:null,
    initialize: function($super, field, required, radiobutton, group, errorField, input) {
        $super(field, required, radiobutton, group, errorField);
        this.input = $(input);
    },

    disable:function() {
        this.input.disabled = true;
    },

    enable: function() {
        this.input.disabled = false;
    },

    isValid:function() {
        if (!this.required) return true
        if (this.input.value != '') return true
        return false
    }

});


AsariWeb.SimpleColumnMapping = Class.create(AsariWeb.Mapping, {
    select: null,
    initialize: function($super, field, required, radiobutton, group, errorField, select) {
        $super(field, required, radiobutton, group, errorField);
        this.select = $(select);
    },

    isValid: function() {
        if (!this.required) return true;
        if (this.select.value != '') return true;
        return false;
    },

    disable:function() {
        this.select.disabled = true;
    },

    enable: function() {
        this.select.disabled = false;
    }

});

AsariWeb.DictionaryColumnMapping = Class.create(AsariWeb.SimpleColumnMapping, {

    windowLink :null,
    winDiv:null,
    mappingTableDiv:null,
    dictionary:null,
    windowTitle:null,
    xlsColumnsMetadata:null,

    initialize: function($super, field, required, radiobutton, group, errorField, select, windowLink, windowDiv, windowTitle, mappingTableDiv, dictionary, xlsColumnsMetadata) {
        $super(field, required, radiobutton, group, errorField, select);
        this.windowLink = $(windowLink);
        this.windowDiv = $(windowDiv);
        this.windowTitle = windowTitle;
        this.mappingTableDiv = $(mappingTableDiv);
        this.dictionary = dictionary;
        this.xlsColumnsMetadata = xlsColumnsMetadata;
        this.select.observe('change', this.onColumnSelect.bind(this));
        this.windowLink.observe('click', this.openWindow.bind(this));
    },

    disable:function($super) {
        $super();
        this.windowLink.hide();
    },

    enable: function($super) {
        $super();
        if (this.select.value)
            this.windowLink.show();
    },

    isValid: function() {
        if (!this.required) return true;
        if (!this.select.value) return false;
        var hasEmptyMapping = this.mappingTableDiv.getElementsBySelector('select').any(function(select) {
            return (select.value == '');
        });
        return !hasEmptyMapping;
    },

    onColumnSelect: function() {
        if (this.select.value) {
            this.windowLink.show();
            this.fillMapping();
            this.openWindow();
        } else {
            this.clearMapping();
            this.windowLink.hide();
        }
    },

    setMapping: function(mapping) {
        this.enable()
        this.windowLink.show();
        this.fillMapping(mapping);
    },

    fillMapping: function(mapping) {
        var i = 0;
        var mapping = mapping ? mapping : {};
        var uniqeValues = $A(this.xlsColumnsMetadata).find(function(column) {
            return column.name == this.select.value
        }.bind(this)).uniqeValues;
        var rows = uniqeValues.collect(function(uniqeValue) {
            var from = this.field + '_from.' + i;
            var tr = Builder.node('tr', [
                Builder.node('td',
                        ['' + uniqeValue + '',Builder.node('input', {name:from,type:'hidden',value:'' + uniqeValue + ''})]),

            ]);
            var td = Builder.node('td');
            var to = this.field + '_to.' + i;
            var select = Builder.node('select', {name:to,autocomplete:'off'});
            var emptyOption = Builder.node('option', {value:'',selected:'selected'}, '');
            select.appendChild(emptyOption);
            var selectedIndex = 0;
            var j = 0;
            this.dictionary.each(function(definition) {
                j++;
                if (mapping && definition.value == mapping[uniqeValue])
                    selectedIndex = j;
                var option = Builder.node('option', {value:definition.value}, definition.name);
                select.appendChild(option);
            })
            td.appendChild(select);
            tr.appendChild(td);
            select.selectedIndex = selectedIndex;
            i++;
            return tr;
        }.bind(this));
        var table = Builder.node('table', [
            Builder.node('tbody', rows)
        ]);
        this.mappingTableDiv.update(table);
    },

    clearMapping: function() {
        this.mappingTableDiv.update('');
    },

    openWindow :function() {
        var opts = $H({
            title: this.windowTitle,
            resizable: false,
            draggable: false,
            destroyOnClose: true,
            recenterAuto:true,
            showEffect:Element.show,
            hideEffect:Element.hide,
            width:300,
            height:170,
            onClose: function() {
                $(this.windowDiv).hide()
            }.bind(this)
        });
        var win = new Window(this.field + '_mappingDialog', opts.toObject());
        win.setContent(this.windowDiv, true, true)
        win.showCenter(true);
    }
});

AsariWeb.MultipleColumnMapping = Class.create(AsariWeb.Mapping, {
    columnsSpan: null,
    addLink:null,
    xlsColumnsMetadata:null,


    initialize: function($super, field, required, radiobutton, group, errorField, columnsSpan, addLink, xlsColumnsMetadata) {
        $super(field, required, radiobutton, group, errorField);
        this.columnsSpan = $(columnsSpan);
        this.xlsColumnsMetadata = xlsColumnsMetadata;
        this.addLink = $(addLink);
        this.addLink.observe('click', this.addField.bind(this));
        this.addField();
    },



    addField: function(selectedColumn) {
        var selectedColumn = selectedColumn ? selectedColumn : null;
        var columnSpan = Builder.node('span', {name:this.field + '_column',autocomplete:'off'});
        var linkSpan = Builder.node('span', {style:'cursor:pointer'}, '[-]');
        linkSpan.observe('click', function() {
            columnSpan.remove()
        });
        var select = Builder.node('select', {name:this.field + '_column',autocomplete:'off'});
        var emptyOption = Builder.node('option', {value:'',selected:'selected'}, '');
        select.appendChild(emptyOption);
        var j = 0;
        var selectedIndex = 0;
        this.xlsColumnsMetadata.each(function(column) {
            j++;
            if (selectedColumn == column.name)
                selectedIndex = j;
            var option = Builder.node('option', {value:column.name}, column.name);
            select.appendChild(option);
        })
        select.selectedIndex = selectedIndex;
        columnSpan.appendChild(select);
        columnSpan.appendChild(linkSpan);
        this.columnsSpan.appendChild(columnSpan);
    },

    isValid: function() {
        if (!this.required) return true;
        var selects = this.columnsSpan.getElementsBySelector('select');
        if (selects.size() == 0)
            return false
        var hasEmptyMapping = selects.any(function(select) {
            return (select.value == '');
        });
        return !hasEmptyMapping;
    },

    removeFields:function() {
        this.columnsSpan.update('');
    },

    disable:function() {
    },

    enable: function() {
    }

});


