﻿if (typeof jQuery == 'undefined') {  
   alert('Error: jQuery v1.4.2 has not been loaded!');  
} else {
    var _counter = 0
    get_next_val = function(){
        return ++_counter;
    }
    
    // Represents ability to add multiple files
    MultipleUploadFiles = function(divPanelId, newFileId, clearRes){
        this._divPanelId = divPanelId;
        this._newFileId = newFileId;
        this._clearRes = clearRes;
        this.add_file();    
        this._cur_count = 0;
    }
    MultipleUploadFiles.prototype = {
        _max_count : 10,
        _cur_count : 0,
        
        get_panel : function(){
            return jQuery(this._divPanelId);
        },

        get_filesPanel : function(){
            return jQuery('.files', this._divPanelId);
        },
                
        clear : function(){
            this.get_filesPanel().html('');
            this._cur_count = 0;
            this.add_file();
        },
        
        add_file : function(){
            var self = this;
            if (self._cur_count >= self._max_count) return;
            
            var div = jQuery('<div style="padding-top: 5px"><input type="file" name="' + this._newFileId + get_next_val() + '" />&nbsp;</div>')
                .appendTo(this.get_filesPanel());
                
            jQuery('input', div)    
                .bind('change', function(){
                    var e = jQuery(this);
                    if (!e.attr('hasFile')){
                        self._cur_count++;
                        self.add_file();
                        jQuery('<input type="button" value="'+self._clearRes+'" />')
                            .appendTo(jQuery(this).parent())
                            .click(function(){
                                var del = $(this);
                                del.parent().remove();
                                self._cur_count--;                                
                                if (self._cur_count == self._max_count - 1)
                                    self.add_file();
                            })  
                    } 
                    e.attr('hasFile', true);
                });
        }
    }


    // Represents map loaded
    MapManager = function(placeHolderElemId, maps, onAreaCreated) {
        this._placeHolderElemId = placeHolderElemId; // it should be div
        this._imgId = placeHolderElemId + "Img";
        this._maps = maps;
        this._onAreaCreated = onAreaCreated;
    }
    MapManager.prototype = {
        _curMap: null,
        _selected: null,
        _selectedName: null,
        _curMapName: null,
        onGetMap: null,

        // get the element whether the are should be represented
        get_placeholderSelectElement: function() {
            if (!this._selContainer)
                this._selContainer = jQuery('<div></div>')
                    .appendTo(this.get_placeholderElement());
            return this._selContainer;
        },

        // get the element whether the are should be represented
        get_placeholderElement: function() {
            var res = jQuery('#' + this._placeHolderElemId);
            if (res.size() != 1)
                throw new Error("There is has to be placeholder element for location maps");
            return res;
        },

        // gets image element
        get_imageElement: function() {
            var img = jQuery("#" + this._imgId);
            if (img.size() == 0)
                img = jQuery('<img border="0" id="' + this._imgId + '" />')
                    .appendTo(this.get_placeholderSelectElement());
            return img;
        },

        _get_areaUrl: function(map) {
            if (this.onGetMap)
                return this.onGetMap(this, map)
            return '#'
        },

        alerted: false,
        // loads map by name
        loadMap: function(name) {
            if (!name)
                throw new Error("There is has to be setted name");
            var map = this._maps[name];
            if (!map)
                throw new Error("There is has to be location with name " + name);
            if (map) {
                if (map.length == 0)
                    throw new Error('Each map must contain at least one area');

                var area, i, shape, map;
                this.get_placeholderElement().children().remove();

                this._selContainer = null;
                this._selected = null;

                var mapId = this._placeHolderElemId + "Map" + get_next_val();
                mapElement = jQuery('<map name="' + mapId + '" id="' + mapId + '"></map>')
                mapElement.bind('mouseout', function() {
                    window.setTimeout(function() {
                        if (!self._over) {
                            if (self._selected)
                                self.showMapImage(name, self._selected[1], self.get_imageElement());
                            else
                                self.showMapImage(name, rootArea[1], self.get_imageElement())
                        }
                    }, 100);
                })

                var self = this;
                var rootArea = map[0];
                for (i = 1; i < map.length; i++) {
                    shape = (map[i].length > 3 ? map[i][3] : "poly");

                    var coords = '';
                    var c = map[i][2].split(',');
                    for (var j = 0; j < c.length; j++)
                        coords += c[j].toString() + ", ";
                    area = jQuery('<area shape="' + shape + '" href="' + this._get_areaUrl(map[i]) + '" idx="' + i + '" alt="' + map[i][0] + '" onclick="return false"></area>');
                    //area.attr("coords", map[i][2].toString());
                    area.attr("coords", coords);

//                    if (!this.alerted) {
//                        alert(area.attr("coords") + "-----" + map[i][2] + "----------" + coords);
//                        this.alerted = true;
//                    }
                    area.bind('mouseover', function() {
                        var idx = $(this).attr('idx');
                        var selected = self._maps[name][idx];
                        self.showMapImage(name, selected[1], self.get_imageElement())
                        tooltip.show('<b>' + selected[0] + '</b>');
                        self._over = true;
                    }).bind('mouseout', function() {
                        tooltip.hide();
                        self._over = false;
                    });

                    if (this._onAreaCreated)
                        this._onAreaCreated(area, map[i], name, self);

                    area.click(function() {
                        var idx = $(this).attr('idx');
                        self._selected = self._maps[name][idx];
                        self.showMapImage(name, self._selected[1], self.get_imageElement())
                    });
                    area.appendTo(mapElement);
                    area.html(area.html());
                }

                this.get_placeholderElement().html('');
                this.get_imageElement().attr("usemap", "#" + mapId);
                mapElement.insertAfter(this.get_imageElement());
                this.get_imageElement().attr('src', this.getMapSrc(name, rootArea[1]));

                this.get_placeholderElement().css('background', 'url(' + this.getMapSrc(name, rootArea[1]) + ') no-repeat 50% 0px');
                this.get_placeholderSelectElement().css('background', 'url(' + this.getMapSrc(name, rootArea[1]) + ') no-repeat 50% 0px');

                this._curMap = map;
                this._curMapName = name;
                this._selectedName = name
            }
        },

        // shows image map
        showMapImage: function(provinceName, imgName, rollElem) {
            rollElem.attr("src", this.getMapSrc(provinceName, imgName));
            if (this._selected)
                this.get_placeholderSelectElement().css('background', 'url(' + this.getMapSrc(provinceName, this._selected[1]) + ') no-repeat 50% 0px');
        },

        // hides selected map
        hideSelectedMapImage: function() {
            tooltip.hide();
            var self = this
            window.setTimeout(function() {
                self.get_placeholderSelectElement().css('background', self.get_placeholderElement().css('background'))
                self.get_imageElement().attr('src', self.getMapSrc(self._selectedName, self._curMap[0][1]));
            }, 1)
        },

        // gets url for image
        getMapSrc: function(provinceName, imgName) {
            return '/img/maps/' + provinceName + '/' + imgName + '.gif';
        },

        // selects certain area
        selectInnerArea: function(location) {
            for (var i = this._curMap.length - 1; i >= 0; i--) { //we should start from end because of having the same name inside container
                if (jQuery.convertToEnglishLetters(this._curMap[i][0], true) == location) {
                    this._selected = this._curMap[i];
                    this.showMapImage(this._curMapName, this._selected[1], this.get_imageElement())
                    return this._curMap[i][0];
                }
            }
            return false;
        }
    }

    /* Represents location select list */
    LocationSelect = function(containerId, maps, onChange) {
        this._containerId = containerId;
        this._onChange = onChange;
        if (!maps)
            throw Error('The maps cannot be null!');
        this._maps = maps;
    }
    LocationSelect.prototype = {
        onGetUrl: null,
        // gets selected map
        get_selected: function() {
            return this._selected;
        },

        // sets selected map
        set_selected: function(value) {
            if (!value) throw Error('The value cannot be null');
            this._selected = value;
        },

        _get_url: function(map) {
            if (this.onGetUrl)
                return this.onGetUrl(this, map)
            return '#'
        },

        _renderHeader: function(value) {
            if (!this._header) throw Error("There is no header to render");
            this._header.attr('value', value).css('background-color', '#FFFFFF');
            this._header.html(value + '&nbsp;<span>▼</span>');
        },

        // renders element
        render: function(state) {
            if (this._selected == null) throw Error('The selected value has to be initialized');

            var self = this;
            $(this._containerId)
                .bind('mouseover', function() { self.open() })
                .bind('mouseout', function() { self.close() })
            var ul = jQuery("<ul></ul>").appendTo(this._containerId);

            var li = jQuery("<li></li>").appendTo(ul);
            var h2 = jQuery('<h2></h2>').appendTo(li)
            this._body = jQuery("<ul></ul>")
                .bind('scroll', function() {
                    self._scrollTop = $(self._body).scrollTop();
                })
                .appendTo(li);

            for (var location in this._maps) {
                var item = jQuery('<a location="' + location + '" value="' + this._maps[location][0][0] + '" title="' + getRes("Common_PropertyIn") + this._maps[location][0][0] + '" onclick="return false">' + this._maps[location][0][0] + '</a>')
                item.attr("href", this._get_url(this._maps[location][0]))
                item.click(function() {
                    self._onClickHandler($(this));
                })
                    .appendTo(jQuery("<li></li>").appendTo(this._body))
                if (this._selected == this._maps[location]) {
                    item.css('background-color', '#F0F0F0').attr('active', 'true');
                    this._selLocation = location;
                }
            }

            this._header = jQuery('<a href="" location="' + this._selLocation + '" onclick="return false"></a>').appendTo(h2);
            this._header.css('width', 'auto');
            this._renderHeader(this._selected[0][0]);
            this._header.click(function() { self._onClickHandler($(this)); });

            if (state) this.open(true);
            else this.close(true);

        },

        reRender: function(location, value) {
            this._selected = this._maps[location];
            this._header.attr('location', location);
            jQuery('a[active]', this._body).css('background-color', '#FFFFFF').removeAttr('active');
            jQuery('a[location^=' + location + ']', this._containerId).css('background-color', '#F0F0F0').attr('active', 'true'); // should be element where press was
            this._renderHeader(value);
            this.close(true);
            this.close(false);
        },

        _onClickHandler: function(sender) {
            var location = sender.attr('location');
            var value = sender.attr('value');
            if (this._onChange(this, location, value))
                this.reRender(location, value)
        },

        // opens all provinces
        open: function(rightNow) {
            if (rightNow) {
                $(this._body).css('display', '');
                if (this._scrollTop && this._scrollTop > 0)
                    $(this._body).stop().scrollTo(this._scrollTop, 0, { queue: true });
            }
            else {
                var self = this;
                this._visible = true;
                window.setTimeout(function() { self._changeVisible() }, 200);
            }
        },

        // closes all provinces
        close: function(rightNow) {
            if (rightNow)
                this._body.css('display', 'none');
            else {
                var self = this;
                this._visible = false;
                window.setTimeout(function() { self._changeVisible() }, 200);
            }
        },

        _changeVisible: function() {
            var visible = ($(this._body).css('display') != 'none');
            if (visible != this._visible)
                $(this._body).css('display', (this._visible ? '' : 'none'));

            if (this.visible || !jQuery.browser.mozilla) {
                if (this._scrollTop && this._scrollTop > 0)
                    $(this._body).stop().scrollTo(this._scrollTop, 0, { queue: true });
            }
        }
    }

    /*Represents location list*/
    LocationList = function(containerId) {
        this._containerId = containerId;
    }
    LocationList.prototype = {
        _locations: null,
        _locationName: null,
        _rootLocationName: null,
        onGetItemText: null,
        onGetGroupText: null,
        onGetAllItemsText: null,

        // gets container whether the locations will be rendered
        get_container: function() {
            var res = jQuery('#' + this._containerId);
            if (res.size() == 0) throw Error('Cannot find container for LocationList');
            return res;
        },

        // renders locations
        render: function(locations, locationName, searchInsideFirst, maxDeep) {
            if (locationName)
                locationName = locationName.trim();
            //if (this._locations == locations && this._locationName == locationName) return;

            this._locations = locations;
            this._locationName = locationName;
            this._rootLocationName = null;

            this.get_container().children().remove();
            var content = '';
            var deep = 1;

            var firstNode = locations;
            if (locations instanceof Array)
                content = this._renderArray(locations, locationName, 4, deep, maxDeep)
            else {
                for (var item in locations) {
                    if (!this._rootLocationName)
                        this._rootLocationName = item;
                    var f = false;
                    if (searchInsideFirst) {
                        for (var innerItem in locations[item])
                            if (innerItem.trim().replace(/(´|’)/g, "'") == locationName.replace(/´/g, "'")) {
                            firstNode = locations[item][innerItem];
                            content = this._renderObj(locations[item][innerItem], innerItem, 2, deep, maxDeep);
                            f = true;
                            break;
                        }
                        if (f) break;
                    }

                    if (!locationName || item.trim().replace(/(´|’)/g, "'") == locationName.replace(/´/g, "'")) {
                        if (locations[item] instanceof Array)
                            content = this._renderArray(locations[item], locationName, 1, deep, maxDeep)
                        else
                            content = this._renderObj(locations[item], item, 1, deep, maxDeep); //level: 0 - province, 1 - county, 2 - municip, 5 costa
                        break;
                    }

                    if (!searchInsideFirst) {
                        for (var innerItem in locations[item])
                            if (innerItem.trim().replace(/(´|’)/g, "'") == locationName.replace(/´/g, "'")) {
                            firstNode = locations[item][innerItem];
                            content = this._renderObj(locations[item][innerItem], innerItem, 2, deep, maxDeep);
                            f = true;
                            break;
                        }
                    }
                }
            }

            jQuery(content).appendTo(this.get_container());

            return firstNode;
        },

        _renderObj: function(locations, name, level, deep, maxDeep) {
            if (deep <= maxDeep) {
                var innerRes = '';
                for (var item in locations) {
                    if (locations[item] instanceof Array) {
                        innerRes += this._renderArray(locations[item], item, level, deep, maxDeep);
                    }
                    else
                        innerRes += this._renderObj(locations[item], item, level + 1, deep + 1, maxDeep);
                }

                return this.get_groupAllElement(name, level, deep) +
                   '<optgroup label="' + this.get_groupText(name, level, deep) + '"></optgroup>' + innerRes;
            }
            return '<option value="' + name + '">' + this.get_itemText(name, level + 1, deep + 1) + '</option>';
            //return '<option value="' + this.get_itemText(name, level + 1, deep + 1) + '">' + this.get_itemText(name, level + 1, deep + 1) + '</option>';
        },

        _renderArray: function(locations, name, level, deep, maxDeep) {
            var res = '';
            if (deep <= maxDeep) {
                for (var i = 0; i < locations.length; i++)
                    res += '<option value="' + locations[i] + '">' + this.get_itemText(locations[i], level + 1, deep + 1) + '</option>';
                //res += '<option value="' + this.get_itemText(locations[i], level + 1, deep + 1) + '">' + this.get_itemText(locations[i], level + 1, deep + 1) + '</option>';
                res = this.get_groupAllElement(name, level + 1, deep + 1) +
                    '<optgroup label="' + this.get_groupText(name, level + 1, deep + 1) + '"></optgroup>' + res;
            }
            return res;
        },

        get_groupText: function(str, level, deep) {
            if (this.onGetGroupText)
                return this.onGetGroupText(this, str, level, deep);
            return str + "...";
        },

        get_groupAllElement: function(str, level, deep) {
            var res = null;
            var resVal = null;
            if (this.onGetAllItemsText) {
                res = this.onGetAllItemsText(this, str, level, deep, false);
                resVal = this.onGetAllItemsText(this, str, level, deep, true);
            }
            if (res)
                return '<option value="' + resVal + '">' + res + '</option>';
            //return '<option value="' + str + '">' + res + '</option>';
            return '';
        },

        get_itemText: function(str, level, deep) {
            if (this.onGetItemText)
                return this.onGetItemText(this, str, level, deep);
            return str;
        }
    }

    // Represents parser which transforms any locations to the array of location names
    LocationParser = function() {
    }
    LocationParser.prototype = {
        _current: null,
        _priorLocations: null,

        //parses locations and returns array of names
        parse: function(locations) {
            if (!locations) return new Array();
            if (locations == this._priorLocations) return this._current;
            if (locations instanceof Array)
                this._current = locations;
            else {
                this._current = [];
                this._parse(locations);
            }
            this._priorLocations = locations;
            return this._current;
        },

        _parse: function(source) {
            if (source == null) return;

            if (source instanceof Array)
                this._parseArray(source);
            else this._parseObject(source);
        },

        _parseObject: function(source) {
            for (var prop in source)
                this._current.push(prop);
            for (var prop in source)
                this._parse(source[prop]);
        },

        _parseArray: function(source) {
            for (var i = 0; i < source.length; i++)
                this._current.push(source[i]);
        }
    }

    LocationLinkList = function(containerId) {
        this._containerId = containerId
    }
    LocationLinkList.prototype = {
        onCreate: null,
        dataSource: null,

        _onCreate: function(sender, target, data) {
            if (this.onCreate)
                return this.onCreate(sender, target, data);
            return true;
        },

        get_container: function() {
            return jQuery(this._containerId)
        },

        render: function() {
            var container = this.get_container();
            var ul = jQuery("<ul></ul>");
            for (var i = 0; i < this.dataSource.length; i++) {
                var li = jQuery('<li></li>');
                var a = jQuery('<a></a>').appendTo(li);
                if (this._onCreate(this, a, this.dataSource[i])) {
                    li.appendTo(ul);
                }
            }
            ul.appendTo(container);
        }
    }
}
