/**
 * @constructor
 * @class Address
 */
var Address = new JS.Class({
    /**
     */
    initialize: function() {
         this.address1 = this.address2 = this.city = this.county =
                this.country = this.postcode = "";
    },
    
    /**
     * @returns {String}
     */
    toString: function() {
        var self = this;
        return jQuery.map(this.klass.FIELDS, function(key) { return self[key] }).join(', ');
    },
    
    /**
     * @returns {String}
     */
    toShortAddress: function() {
        return this.address1 + (this.address2 ? ', ' + this.address2 : '') + ', ' + this.city;
    },
    
    extend: {
        /**
         * @param {XMLDocument} xml
         * @returns {Array}
         */
        fromXML: function(xml) {
            var doc = xml.documentElement;
            var addressNodes = doc.getElementsByTagName('address');
            var addresses = [], address, node;
            
            for (var i = 0, n = addressNodes.length; i < n; i++) {
                node = addressNodes.item(i).firstChild,
                address = new this;
                addresses.push(address);
                
                while (node) {
                    if (node.nodeType == 1 && node.firstChild)
                        address[node.nodeName] = node.firstChild.data;
                    node = node.nextSibling;
                }
            }
            return addresses;
        },
        
        FIELDS: 'address1 address2 city county country postcode'.split(' ')
    }
});

/**
 * @constructor
 * @class PostcodeLookup
 */
var PostcodeLookup = new JS.Class({
    extend: {
        PATTERNS: {
            POSTCODE:   /[a-z]{1,2}[0-9][0-9a-z]?[0-9][a-z]{2}/i,
            SPACES:     / /g
        }
    },
    
    /**
     * @param {String} formId
     * @param {String} url
     */
    initialize: function(formId, url) {
        this._id = formId;
        this._selectBox = jQuery.byId(formId + 'addressSelect');
        this._lookupButton = jQuery.byId(formId + 'autoFillAddress');
        this._postcodeField = jQuery.byId(formId + 'postCodeUk');
        this._url = url;
        
        var self = this;
        this._lookupButton
        .bind('click', function() {
            self.lookupAddress();
            return false;
        })
        .bind('mouseover', function() {
            jQuery(this).addClass('hover');
        })
        .bind('mouseout', function() {
            jQuery(this).removeClass('hover');
        });
    },
    
    /**
     * @param {String} name
     * @returns {DomCollection}
     */
    getFormElement: function(name) {
        return jQuery.byId(this._id + name);
    },
    
    /**
     */
    lookupAddress: function() {
        var postcode = this._postcodeField.attr('value');
        if (!postcode) return;
        this._lookupButton.attr('value', 'Please wait...');
        var self = this;
        jQuery.post(this._url, {postcode: postcode}, function(response) {
            var addresses = self._addresses = Address.fromXML(response);
            self.populateSelect(addresses);
            self._lookupButton.attr('value', 'Autofill address...');
        });
    },
    
    /**
     * @param {Array} addresses
     */
    populateSelect: function(addresses) {
        var html;
        if (addresses.length === 0) {
            html = "<option>No addresses found</option>";
        } else {
            html = "<option>Please select an address</option>";
            jQuery.each(addresses, function(i, address) {
                html += '<option value="' + i + '">' + address.toShortAddress() + '</option>';
            });
        }
        html = '<label for="addressSelect"><strong>Select address</strong></label><select style="width:250px!important;" id="' + this._id + 'addresses">' + html + '</select>';
        this._selectBox.html(html);
        this._addressSelect = jQuery.byId(this._id + "addresses");
        this._addressSelect.bind('change', this.method('_selectAddress'));
    },
    
    /**
     */
    _selectAddress: function() {
        var index = Number( this._addressSelect.attr('value') );
        var address = this._addresses[index];
        
        var self = this;
        jQuery.each(Address.FIELDS, function(i,field) {
            var element = self.getFormElement(field);
            element.attr('value', address[field]);
        });
        
        this._selectBox.html('');
    }
});

jQuery.byId = function(id) {
    return jQuery(document.getElementById(id));
};