var addressStorage = new Object;
addressModule = function (params) {
    this.accepted=false;
    this.unique=objSize(addressStorage);
    addressStorage[this.unique]=new Object;
    this.countryCode=(params && params.countryCode)?(params.countryCode):('HU');
    this.lat=(params && params.lat)?(params.lat):(0);
    this.lng=(params && params.lng)?(params.lng):(0);
    this.zoom=(params && params.zoom)?(params.zoom):(15);
    this.address=(params && params.address)?(params.address):('#address');
    this.position=(params && params.position)?(params.position):('#position');
    this.country=(params && params.country)?(params.country):('#country');
    this.city=(params && params.city)?(params.city):('#city');
    this.zip=(params && params.zip)?(params.zip):('#zip');
    this.street=(params && params.street)?(params.street):('#street');
    this.house=(params && params.house)?(params.house):('#house');
    this.geo=(params && params.geo)?(params.geo):('#geo');
    this.pointAcceptText=(params && params.pointAcceptText)?(params.pointAcceptText):('');
    this.mapCloseText=(params && params.mapCloseText)?(params.mapCloseText):('');
    this.addressNotFoundText=(params && params.addressNotFoundText)?(params.addressNotFoundText):('');
    this.geoCodeNotFoundText=(params && params.geoCodeNotFoundText)?(params.geoCodeNotFoundText):('');
    $(this.address).bind('focus', this, function (e) {e.data.showMap.apply(this, arguments)});
    $(this.address).bind('change', this, function (e) {e.data.showAddressOnMap.apply(this, arguments)});
    $(this.zip).bind('focus', this, function (e) {e.data.showMap.apply(this, arguments)});
    $(this.zip).bind('change', this, function (e) {e.data.showAddressOnMap.apply(this, arguments)});
    $(this.city).bind('focus', this, function (e) {e.data.showMap.apply(this, arguments)});
    $(this.city).bind('change', this, function (e) {e.data.showAddressOnMap.apply(this, arguments)});
    $(this.street).bind('focus', this, function (e) {e.data.showMap.apply(this, arguments)});
    $(this.street).bind('change', this, function (e) {e.data.showAddressOnMap.apply(this, arguments)});
    $(this.house).bind('focus', this, function (e) {e.data.showMap.apply(this, arguments)});
    $(this.house).bind('change', this, function (e) {e.data.showAddressOnMap.apply(this, arguments)});
    $(this.country).bind('focus', this, function (e) {e.data.showMap.apply(this, arguments)});
    $(this.country).bind('change', this, function (e) {e.data.showAddressOnMap.apply(this, arguments)});

    addressStorage[this.unique].geocoder = new google.maps.Geocoder();
    addressStorage[this.unique].latlng = new google.maps.LatLng(this.lat, this.lng);
    addressStorage[this.unique].mapOptions = {
        zoom: this.zoom,
        center: addressStorage[this.unique].latlng,
        mapTypeControl: false,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    this.createMap = function (e) {
        var app=e.data;
        if(typeof addressStorage[app.unique].mapObject == 'undefined') {
            app.layer=$('<div />');
            app.layer.attr('id', 'addressMapLayer'+app.unique);
            app.layer.addClass('addressMapLayer');
            app.layer.prependTo($(this).parent());
            app.layer.show();
            app.map=jQuery('<div />');
            app.map.attr('id', 'addressMapCanvas'+app.unique);
            app.map.addClass('addressMapCanvas').prependTo(app.layer);
            app.map.show();
            //app.accept=$('<button />').attr('id', 'addressMapAcceptButton'+app.unique).addClass('addressMapAcceptButton').attr('type', 'button').html(app.pointAcceptText).hide().prependTo(app.layer);
            //app.info=$('<div />').attr('id', 'addressMapInfo'+app.unique).addClass('addressMapInfo').prependTo(app.layer);
            app.close=$('<button type="button"/>');
            app.close.attr('id', 'addressMapCloseButton'+app.unique);
            //app.close.attr('type', 'button');
            app.close.addClass('addressMapCloseButton')
            app.close.html(app.mapCloseText).prependTo(app.layer);
            app.close.bind('click', app, app.hideMap);
            //app.accept.bind('click', app, app.acceptAddress);
            addressStorage[app.unique].mapObject = new google.maps.Map(document.getElementById('addressMapCanvas'+app.unique), addressStorage[app.unique].mapOptions);
        }
    };
    this.showMap = function (e) {
        var app=e.data;
        app.createMap.apply(this, arguments);
        var position=$(app.position).position();
        app.layer.css({
            left: position.left+$(app.position).outerWidth(),
            top:  position.top,
            position: 'absolute',
            marginTop: 0,
            marginLeft: 0

        });
        app.layer.fadeIn();
    };
    this.hideMap = function (e) {
        var app=e.data;
        app.layer.fadeOut();
    };
    this.retrieveDetailedAddressFromResult = function (app, result) {
        if (result.address_components) {
            addressStorage[app.unique].house='';
            addressStorage[app.unique].street='';
            addressStorage[app.unique].city='';
            addressStorage[app.unique].country='';
            addressStorage[app.unique].zip='';
            for (var i=0; i < objSize(result.address_components); i++) {
                if (result.address_components[i].types[0] == 'street_number') {addressStorage[app.unique].house = result.address_components[i].long_name;}
                if (result.address_components[i].types[0] == 'route') {addressStorage[app.unique].street = result.address_components[i].long_name;}
                if (result.address_components[i].types[0] == 'locality') {addressStorage[app.unique].city = result.address_components[i].long_name;}
                if (result.address_components[i].types[0] == 'country') {addressStorage[app.unique].country = result.address_components[i].long_name;}
                if (result.address_components[i].types[0] == 'postal_code') {addressStorage[app.unique].zip = result.address_components[i].long_name;}
            };
        }
        addressStorage[app.unique].outputAddress=result.formatted_address;
        addressStorage[app.unique].outputAddressLocation=result.geometry.location;
        addressStorage[app.unique].result=result;
        //app.info.html(result.formatted_address);
        app.accept.show();
    };
    this.showAddressOnMap = function (e) {
        var app=e.data;
        app.accepted = false;
        //app.accept.hide();
        if ($(app.address).val() && $(app.address).val().length > 0) {
            var inputAddress=$(app.address).val();
        } else {
            var inputAddress= $(app.zip).val() + " " + $(app.city).val() + "," + $(app.street).val() + " " + $(app.house).val() /*+ ", " + $(app.country).val()*/;
        }
        addressStorage[app.unique].inputAddress=inputAddress;
        var countryCode=app.countryCode;
        //var address = $('#offerPlace').val();
        if (addressStorage[app.unique].geocoder) {
            addressStorage[app.unique].geocoder.geocode({
                'address': inputAddress,
                'country' : countryCode
            },
            function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    addressStorage[app.unique].mapObject.setCenter(results[0].geometry.location);
                    if (! addressStorage[app.unique].absoluteMarker) {
                        /*
                        app.retrieveDetailedAddressFromResult(app, results[0]);
                        */
                        addressStorage[app.unique].draggedCoord=results[0].geometry.location;
                        $(app.geo).val(addressStorage[app.unique].draggedCoord.lat()+','+addressStorage[app.unique].draggedCoord.lng());
                        //onsole.log('first'+$(app.geo).val());
                        addressStorage[app.unique].absoluteMarker = new google.maps.Marker({
                            draggable: true,
                            position: results[0].geometry.location,
                            map: addressStorage[app.unique].mapObject
                        });
                        google.maps.event.addListener(addressStorage[app.unique].absoluteMarker, 'dragend',
                            function(e) {
                                var latlng = this.getPosition();
                                addressStorage[app.unique].draggedCoord=latlng;
                                $(app.geo).val(addressStorage[app.unique].draggedCoord.lat()+','+addressStorage[app.unique].draggedCoord.lng());
                                //onsole.log('event'+$(app.geo).val());
                                /*
                                if (addressStorage[app.unique].geocoder) {
                                    addressStorage[app.unique].geocoder.geocode({
                                        'latLng': latlng
                                    },
                                    function(results, status) {
                                        if (status == google.maps.GeocoderStatus.OK) {
                                            if (results[0]) {
                                                app.retrieveDetailedAddressFromResult(app, results[0]);
                                            }
                                        }
                                        else {
                                            app.info.html(app.geoCodeNotFoundText + status);
                                            app.accept.hide();
                                        }
                                    });
                                }
                                */
                            }
                        );
                    } else {
                        addressStorage[app.unique].absoluteMarker.setPosition(results[0].geometry.location);
                        addressStorage[app.unique].draggedCoord=results[0].geometry.location;
                        $(app.geo).val(addressStorage[app.unique].draggedCoord.lat()+','+addressStorage[app.unique].draggedCoord.lng());
                        //onsole.log('input'+$(app.geo).val());
                        /*
                        app.retrieveDetailedAddressFromResult(app, results[0]);
                        */
                    }
                } else {
                    //app.info.html(app.addressNotFoundText + status);
                    //app.accept.hide();
                    if (! addressStorage[app.unique].absoluteMarker) {
                        /*
                        app.retrieveDetailedAddressFromResult(app, results[0]);
                        */
                        addressStorage[app.unique].draggedCoord=addressStorage[app.unique].latlng;
                        $(app.geo).val(addressStorage[app.unique].draggedCoord.lat()+','+addressStorage[app.unique].draggedCoord.lng());
                        //onsole.log('first'+$(app.geo).val());
                        addressStorage[app.unique].absoluteMarker = new google.maps.Marker({
                            draggable: true,
                            position: addressStorage[app.unique].latlng,
                            map: addressStorage[app.unique].mapObject
                        });
                    }
                    google.maps.event.addListener(addressStorage[app.unique].absoluteMarker, 'dragend',
                        function(e) {
                            var latlng = this.getPosition();
                            addressStorage[app.unique].draggedCoord=latlng;
                            $(app.geo).val(addressStorage[app.unique].draggedCoord.lat()+','+addressStorage[app.unique].draggedCoord.lng());
                        	//onsole.log('other event'+$(app.geo).val());
                        }
                    );
                }
            });
        }

    };
    this.acceptAddress = function (e) {
        var app=e.data;
        $(app.address).val(addressStorage[app.unique].outputAddress);
        $(app.house).val(addressStorage[app.unique].house);
        $(app.street).val(addressStorage[app.unique].street);
        $(app.city).val(addressStorage[app.unique].city);
        $(app.country).val(addressStorage[app.unique].country);
        $(app.zip).val(addressStorage[app.unique].zip);
        app.accepted = true;
        app.hideMap(e);
    };
    this.getAccepted = function () {
        return this.accepted;
    }
};

function objSize(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};
