/*jslint browser: true, white: false, sloppy: true, maxerr: 200, regexp: false */
/*global jQuery, PCA, Standard */
// code for setting the browser to the associated link from the
// quickjump dropdown
jQuery(document).ready(function () {
    if (!document.getElementById("qjump")) {
        return false;
    }
    document.getElementById("qjump").onchange = function() {
        if (this.value) {
            window.location = this.value;
        }
    };
});
// code to hide/show the provide details input box on the Need help page
function show_insbeforedetails() {
    var id, elt;
    id = "provide-details";
    elt = document.getElementById(id);
    elt.style.display = 'block';
}
function hide_insbeforedetails() {
    var id, elt;
    id = "provide-details";
    elt = document.getElementById(id);
    elt.style.display = 'none';
}

/*
 * (c) All following code is 2009,2010 Oliver Cope. All rights reserved.
 */

// Set up jQuery plugins
(function ($) {

    /* Return all nodes following the closing tag of the current node, in document
    * order
    */
    $.fn.following = function (selector) {
        var context = this;
        $.each(
            $.map(
                this.nextAll(),
                function (n) {
                    var c = $(n);
                    return c.add(c).add(c.children());
                }
            ),
            function () { context = context.add(this); }
        );
        if (this.parentNode) {
            context = context.add(context.parent().following(selector));
        }
        return context.filter(selector);
    };

    /*
    * Attach an event and immediately fire it.
    *
    * The handler will be called with an additional argument of ``true`` on the
    * initial event fire, so handlers can take the following pattern:
    *
    *     $('selector').bindAndFire(
    *         'click',
    *         function (evt, firstfire) {
    *             if (firstfire === true) {
    *                 ...
    *        }
    *        ...
    *          }
    *     );
    */
    $.fn.bindAndFire = function (eventtype, handler) {
        $(this).bind(eventtype, handler).each(
                function () {
                    handler.apply(this, [new $.Event(eventtype), /* firstfire */ true]);
                }
            );
    };
}(jQuery));



var DareInsurance = {};

DareInsurance.init_form_hints = function () {
/* Initialize display of <span class="hint">...</span> elements in form
 * fields
 */
var $ = jQuery;
$('.overhint').each(function () {
    var input,
        hint = this,
        label = $(this).closest('label')[0];

    if ($(label).attr('for')) {
        input = $('#' + $(label).attr('for')).eq(0);
    } else {
        input = $(hint).following('input,textarea').eq(0);
    }
    if (input.length === 0) {
        return;
    }

        input.wrap('<div style="display: inline-block; position: relative"></div>');
        input.before(hint);
        $(hint).css({
            display: 'inline-block',
            position: 'absolute',
            left: '3px',
            top: '3px'
        });
        if (input[0].value) {
            $(this).hide();
        }
        if (!input[0].disabled) {
            $(hint).bind('click', function() { $(hint).hide(); input.focus(); });
            $(input).bind('click', function() { $(hint).hide(); });
            $(input).bind('focus', function() { $(hint).hide(); });
            $(input).bind('blur', function () { if (this.value === '') { $(hint).show(); } });
        }
    });
};

DareInsurance.init_addcommas = function () {
    var $ = jQuery;
    function add_commas(value) {
        var n, ipart, groups, ix;
        n = parseFloat(value.replace(',', ''), 10);
        if (isNaN(n)) {
            return value;
        }

        ipart = String(Math.floor(n));
        groups = [];
        if (ipart.length % 3 !== 0) {
            groups.push(ipart.substring(0, ipart.length % 3));
            ipart = ipart.substring(ipart.length % 3);
        }
        for (ix = 0; ix < ipart.length; ix += 3) {
            groups.push(ipart.substring(ix, ix + 3));
        }
        return groups.join(',') + value.replace(/^[^.]*(\..*)?$/, '$1');
    }
    $('input.addcommas').bindAndFire('change', function () {
        this.value = add_commas(this.value);
    });
};

DareInsurance.postcodeAnywhere = function (input, fields, show_pca_messages) {
    var pca, $, results_div, handler;
    if (show_pca_messages) {
        handler = new DareInsurance.PCAHandler(input);
    }
    pca = new PCA('sport11122', 'ha17-wh72-aj93-ny14');
    $ = jQuery;
    results_div = null;
    input.bind('keyup.pca', function (event) {
        var pcrv = pca.lookup(
            this.value,
            function (data) {
                var address_list, address_row;

                if (results_div) {
                    $(results_div).remove();
                }
                if (data.length === 0) {
                    // No address(es) found for this postcode
                    input.trigger('pca.no_match');
                    return;
                }
                input.trigger('pca.found_postcodes');

                results_div = $('<div class="pca_results"></div>');
                input.after(results_div);
                address_list = $('<ul></ul>');
                results_div.append(address_list);
                $.each(
                    data,
                    function (ix, item) {
                        address_row = $('<li></li>');
                        address_row
                            .text(item.address.slice(0, 3).join(', ') + ' ' + item.Postcode)
                            .data('pca', item);
                        address_list.append(address_row);
                    }
                );
                address_list.click(function (ev) {
                    var pca, address_data;
                    pca = $(ev.target).data('pca');
                    if (!pca || !pca.Postcode) {
                        // Clicked somewhere else?
                        return;
                    }
                    input.val(pca.Postcode);
                    address_data = $.map(
                        ['Line1', 'Line2', 'Line3', 'PostTown', 'County', 'CountryName'],
                        function (item) { return pca[item]; }
                    );
                    $.each(
                        fields,
                        function (ix, item) {
                            input.get(0).form.elements[item].value = address_data[ix];
                        }
                    );
                    results_div.remove();
                    address_list.unbind();

                    input.trigger('pca.chosen_postcode', [pca]);
                });
            }
        );
        if (pcrv === null) {
            // not a valid postcode
            input.trigger('pca.invalid_postcode');
        } else if (pcrv === undefined) {
            input.trigger('pca.looking_up_postcode');
        }
    });
};

DareInsurance.stopPostcodeAnywhere = function(input) {
    // Stop listeners to keyup.pca and pca.* messages.
    jQuery(input).unbind('keyup.pca pca');
    jQuery('.pca_messages').remove();
};

DareInsurance.PCAHandler = function(jq_element) {
    // Show more useful feedback from the PCA.
    var _mesg_elem = $('<span class="pca_messages">...</span>');
    // Pop message in after last sibling.
    jq_element.last().after(_mesg_elem);

    function text(message) {
        _mesg_elem.text(message);
    }

    text('Enter postcode to find address');

    // Update the field annotation according to messages we receive from pca.
    jq_element.bind({
        "pca.no_match": function() { text('No matching postcodes'); },
        "pca.invalid_postcode": function() { text('Not a valid postcode'); },
        "pca.looking_up_postcode": function() { text('Looking up address...'); },
        "pca.found_postcodes": function() { text('Select an address...'); },
        "pca.chosen_postcode": function() { text(''); }
    });
};

/* Return the value as a float if possible; return zero if value is undefined
 * or non-numeric
 */
DareInsurance.numericValue = function(value) {
    // Return the numeric value of ``value`` or zero
    if (value.val !== undefined) {
        value = value.val();
    }
    if (isFinite(parseFloat(value))) {
        return parseFloat(value);
    }
    return 0;
};

/* Do a numeric sum over the given list of fields and return the value.
 */
DareInsurance.numericSum = function(source, fields) {
    var sum = 0;
    $.each(fields, function(idx, field){
        if (source[field]) {
            sum += DareInsurance.numericValue(source[field].value);
        }
    });
    return sum;
};

/* Return true if the given value is a non-zero number */
DareInsurance.isNonZero = function(value) { return DareInsurance.numericValue(value) !== 0; };

/* Return true if the given value is zero, undefined, or non-numeric */
DareInsurance.isZero = function(value) { return DareInsurance.numericValue(value) === 0; };

var DateUtils = {};

DateUtils.is_leap_year = function (y) {
    return new Date(y.getFullYear(), 1, 29).getDate() === 29;
};
DateUtils.days_in_month = function (year, month) {
    if (month === 1 && DateUtils.is_leap_year(new Date(year, month, 1))) {
        return 29;
    }
    return [
        31, // J
        28, // F
        31, // M
        30, // A
        31, // M
        30, // J
        31, // J
        31, // A
        30, // S
        31, // O
        30, // N
        31  // D
    ][month];
};

DateUtils.DAY = 86400000;
DateUtils.months = {
    JANUARY: 0,
    FEBRUARY: 1,
    MARCH: 2,
    APRIL: 3,
    MAY: 4,
    JUNE: 5,
    JULY: 6,
    AUGUST: 7,
    SEPTEMBER: 8,
    OCTOBER: 9,
    NOVEMBER: 10,
    DECEMBER: 11
};

DateUtils.timedelta = function (days) {
    this.ms = days * Standard.DAY;
};
DateUtils.add_months = function (d, count) {
    var result = new Date(d.getTime());
    result.setDate(1);
    result.setMonth(result.getMonth() + count);
    result.setDate(Math.min(
        DateUtils.days_in_month(result.getFullYear(), result.getMonth()),
        d.getDate()
    ));
    return result;
};
DateUtils.add_years = function (d, count) {
    // Leap years: 29 Feb on a leap year is mapped to 1 Mar on a non-leap year
    // Compare with add_months(d, count * 12), which returns 28 Feb
    var result = new Date(d.getTime());
    result.setFullYear(d.getFullYear() + count);
    return result;
};
DateUtils.add_seconds = function (d, count) { return new Date(d.getTime() + count * 1000); };
DateUtils.add_days = function (d, count) { return new Date(d.getTime() + count * DateUtils.DAY); };
DateUtils.add_weeks = function (d, count) { return new Date(d.getTime() + count * 7 * DateUtils.DAY); };
DateUtils.add_minutes = function (d, count) { return DateUtils.add_seconds(d, 60 * count); };
DateUtils.add_hours = function (d, count) { return DateUtils.add_seconds(d, 3600 * count); };

DateUtils.add = function (d, options) {
    /*
     * Standard.timedelta.add(new Date(2001, 1, 1), {days: 1, hours: -5, years: 2 });
     */
    var result = new Date(d.getTime());
    if (options.years) { result = DateUtils.add_years(result, options.years); }
    if (options.months) { result = DateUtils.add_months(result, options.months); }
    if (options.weeks) { result = DateUtils.add_weeks(result, options.weeks); }
    if (options.days) { result = DateUtils.add_days(result, options.days); }
    if (options.hours) { result = DateUtils.add_hours(result, options.hours); }
    if (options.seconds) { result = DateUtils.add_seconds(result, options.hours); }
    return result;
};

jQuery(DareInsurance.init_form_hints);
jQuery(DareInsurance.init_addcommas);

