/**
 * @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() {
        return this.klass.FIELDS.map(function(key) { return this[key] }, this).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 == Ojay.HTML.ELEMENT_NODE && 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 = Ojay.byId(formId + 'select-box');
        this._lookupButton = Ojay.byId(formId + 'look-up-button');
        this._postcodeField = Ojay.byId(formId + 'postcode-lookup');
        this._url = url;
        
        this._lookupButton.on('click')._(this).lookupAddress();
        this._lookupButton.on('mouseover').addClass('hover');
        this._lookupButton.on('mouseout').removeClass('hover');
    },
    
    /**
     * @param {String} name
     * @returns {DomCollection}
     */
    getFormElement: function(name) {
        return Ojay.byId(this._id + name);
    },
    
    /**
     */
    lookupAddress: function() {
        var postcode = this._postcodeField.node.value;
        if (!postcode) return;
        this._lookupButton.node.value = 'Please wait...';
        Ojay.HTTP.GET(this._url, {postcode: postcode}, {
            onSuccess: function(response) {
                var addresses = this._addresses = Address.fromXML(response.responseXML);
                this.populateSelect(addresses);
                this._lookupButton.node.value = 'Autofill address...';
            }.bind(this)
        });
    },
    
    /**
     * @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>";
            addresses.forEach(function(address, i) {
                html += '<option value="' + i + '">' + address.toShortAddress() + '</option>';
            });
        }
        html = '<p><span class="fielddescription"><select id="' + this._id + 'addresses">' + html + '</select></span></p>';
        this._selectBox.setContent(html);
        this._addressSelect = Ojay.byId(this._id + "addresses");
        this._addressSelect.on('change')._(this)._selectAddress();
    },
    
    /**
     */
    _selectAddress: function() {
        var index = Number( this._addressSelect.node.value );
        var address = this._addresses[index];
        
        Address.FIELDS.forEach(function(field) {
            var element = this.getFormElement(field);
            if (address[field]) Ojay.Forms.setValue(element, address[field]);
        }, this);
        
        this.getFormElement(Address.FIELDS[Address.FIELDS.length-1]).node.focus();
        
        this._selectBox.setContent('');
    }
});

