/**
 * @fileoverview
 * A jQuery plugin to implement the number checker. Really, this is how all of
 * our Web widgets (like the call cost calculator) should be implemented. You
 * know, if we had enough time.
 */

/**
 * Constructs a new number checker object.
 *
 * @constructor
 * @param {Object} userOptions Overrides for the default options used when
 * instantiating the number checker. This is probably of most use when
 * tinkering with the messages to be displayed back to the user.
 */
jQuery.fn.numberChecker = function(userOptions) {
    // Default options for the number checker, including default messages.
    var options = {
        backend: "/number-checker.cgi",
        callback: null,
        cookie: "profile",
        messages: {
            onnet_some: "Initial checks show that high speed <strong>broadband2+ and Naked DSL</strong> are available in your area. We'll be able to confirm this upon application; please choose from the options below.",
            onnet_afew: "Initial checks show that high speed <strong>broadband2+ and Naked DSL</strong> are available in your area, but there are only a few places left. We'll be able to confirm this upon application; please choose from the plan options below.",
            onnet_none: "There are currently no broadband2+ places available in your area. Please check back often as ports may free up from time to time. In the meantime, you can select from one of the <strong>broadband1</strong> options shown below.",
            offnet: "The telephone number you supplied supports a <strong>broadband1</strong> connection with speeds up to 8000k. Please choose from one of the broadband1 plan options shown below.",
            transit_some: "Your area is scheduled for an upgrade to broadband2+ in the near future. While you wait for broadband2+ to arrive, we have an exclusive set of plans called <strong>broadband1 transit</strong> available to you. We'll explain more about why you'll like these plans on the next page.",
            transit_afew: "Your area is scheduled for an upgrade to broadband2+ in the near future. While you wait for broadband2+ to arrive, we have an exclusive set of plans called <strong>broadband1 transit</strong> available to you. We'll explain more about why you'll like these plans on the next page.",
            transit_none: "The telephone number you supplied supports a <strong>broadband1</strong> connection with speeds up to 8000k. Please choose from one of the broadband1 plan options shown below.",
            onnet_none_transit_some: "Your area is scheduled for an upgrade to broadband2+ in the near future. While you wait for broadband2+ to arrive, we have an exclusive set of plans called <strong>broadband1 transit</strong> available to you. <a href='/broadband/transit-plans.html'>Find out more about broadband1 transit plans.</a>",
            onnet_none_transit_afew: "Your area is scheduled for an upgrade to broadband2+ in the near future. While you wait for broadband2+ to arrive, we have an exclusive set of plans called <strong>broadband1 transit</strong> available to you. We'll explain more about why you'll like these plans on the next page.",
            onnet_none_transit_none: "There are currently no broadband2+ places available in your area. Please check back often as ports may free up from time to time. In the meantime, you can select from one of the <strong>broadband1</strong> options shown below.",
            dialup: "Unfortunately, ADSL broadband is not currently available on the telephone number you supplied. If you would like an alternative to broadband, please visit our <a href='/dialup/'>dialup</a> section.",
            error: "Sorry, information about your exchange could not be found. Please enter another number to try again.",
            badnumber: "Sorry, information about your exchange could not be found. Please enter another number to try again.",

            offnet_naked: "The telephone number you supplied isn't eligible for Naked DSL because it's not connected to the iiNetwork. Your telephone line will support a <strong>broadband1</strong> connection of up to 8,000kbps. Choose from one of our <a href='/broadband/plans.html'>broadband1 plans</a> or learn more about <a href='https://iihelp.iinet.net.au/Naked_DSL_availability'>Naked DSL eligibility</a>",
            onnet_none_naked: "There are currently no broadband2+ places available in your area. Please check back often as ports may free up from time to time. In the meantime your telephone line will support a <strong>broadband1</strong> connection of up to 8,000kbps. Choose from one of our <a href='/broadband/plans.html'>broadband1 plans</a>. Learn more about <a href='https://iihelp.iinet.net.au/Broadband_availability'>broadband2+ port availability</a>",
            onnet_none_transit_afew_naked: "Your area is scheduled for an upgrade to broadband2+ in the near future. While you wait for broadband2+ to arrive, we have an exclusive set of plans called <strong>broadband1 transit</strong>. Learn more about <a href='/broadband/transit-plans.html'>broadband 1 transit plans</a>",
            onnet_none_transit_none_naked: "There are currently no broadband2+ places available in your area. Please check back often as ports may free up from time to time. In the meantime your telephone line will support a <strong>broadband1</strong> connection of up to 8,000kbps. Choose from one of our <a href='/broadband/plans.html'>broadband 1 plans</a> or learn more about <a href='https://iihelp.iinet.net.au/Broadband_availability'>broadband2+ port availability</a>."
        },
        refer: "https://toolbox.iinet.net.au/one-signup/refer.cgi",
        referDestination: "http://www.iinet.net.au/blank.html",
        template: "/inc/number-checker.html",
        transitionSpeed: "normal"
    };
    if (userOptions) {
        for(var i in userOptions)
            options[i] = userOptions[i];
    }

    var numberChecker = this;

    /**
     * Displays the given message within the number checker element.
     *
     * @param {String} message A HTML message to display.
     */
    var displayResult = function(message) {
        $("form", numberChecker).fadeOut(options.transitionSpeed, function() {
            $(".throbber", numberChecker).remove();
            $(".message", numberChecker).html(message);
            $(".result", numberChecker).fadeIn(options.transitionSpeed);
            $(".try_again", numberChecker).click(onTryAgain);
        });
    };

    /** Displays a throbber to the user while we wait for results. */
    var displayThrobber = function() {
        $("input[type=submit]", numberChecker).after("<img class='throbber' src='/img/Throbber-mac.gif' width='16' height='16' alt='Please wait...' />");
    };
    
    /**
     * Response handler once we have a response from the backend. Parses the
     * response, selects an appropriate message, updates the profile cookie to
     * match the available set of plans, and calls refer.cgi to pre-populate
     * Signup with the phone number that was given.
     *
     * @param {resp} The response from the CGI backend.
     */
    var onResponse = function(resp) {
        var message = null;

        /** Checks if we're looking at naked plans */
        var is_naked = function() {
            var is_naked = /naked-dsl/;
            var url = document.location.toString();
            if (url.match(is_naked))
                is_naked = true;
            else
                is_naked = false;
            return(is_naked);
        }
        
        /* OK, this is spaghetti code at its finest, and the only thing I can
         * say in my defense is that it's no worse than the old number checker.
         * It's also no better. Fail.
         *
         * Basically, we need to look at a whole bunch of variables in the
         * response to figure out what combination we actually got back and
         * then decide which message is presented to the user.
         */
        if (resp.reason == "ok") {
            var exch = resp.exchange;
            if (exch.code) {
                var holding = exch.availability.HOLDING;
                var sss = exch.availability.SSS;
                if (sss) {
                    switch (sss) {
                        case "some":
                            message = options.messages.onnet_some;
                            $.profile("plan", { iinet: true, holding: false });
                            break;
                        case "afew":
                            message = options.messages.onnet_afew;
                            $.profile("plan", { iinet: true, holding: false });
                            break;
                        case "none":
                            if (holding) {
                                if (is_naked()) {
                                    switch (holding) {
                                        case "some":
                                            message = options.messages.onnet_none_transit_some;
                                            $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "afew":
                                            message = options.messages.onnet_none_transit_afew_naked;
                                            $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "none":
                                            message = options.messages.onnet_none_transit_none_naked;
                                            $.profile("plan", { iinet: false, holding: false });
                                            break;
                                        default:
                                            message = options.messages.onnet_none_naked;
                                            $.profile("plan", { iinet: false, holding: false });
                                    }
                                }
                                else {
                                    switch (holding) {
                                        case "some":
                                            message = options.messages.onnet_none_transit_some;
                                            $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "afew":
                                            message = options.messages.onnet_none_transit_afew;
                                            $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "none":
                                            message = options.messages.onnet_none_transit_none;
                                            $.profile("plan", { iinet: false, holding: false });
                                            break;
                                        default:
                                            message = options.messages.onnet_none;
                                            $.profile("plan", { iinet: false, holding: false });
                                    }
                                }
                            }
                            else {
                                if (is_naked())
                                    message = options.messages.offnet_naked;
                                else
                                    message = options.messages.offnet;
                                $.profile("plan", { iinet: false, holding: false });
                            }
                    }
                }

                if (!message && holding) {
                    switch (holding) {
                        case "some":
                            message = options.messages.transit_some;
                            $.profile("plan", { iinet: false, holding: true });
                            break;
                        case "afew":
                            message = options.messages.transit_afew;
                            $.profile("plan", { iinet: false, holding: true });
                            break;
                        case "none":
                            message = options.messages.transit_none;
                            $.profile("plan", { iinet: false, holding: false });
                            break;
                        default:
                            if (is_naked())
                                message = options.messages.offnet_naked;
                            else
                                message = options.messages.offnet;
                            $.profile("plan", { iinet: false, holding: false });
                    }
                }
                
                if (!message) {
                    message = options.messages.offnet;
                    $.profile("plan", { iinet: false, holding: false });
                }

                var transACT = "";
                if (exch.state=="ACT") {
                    transACT = "<br /><br />You might be eligible for the TransACT network. <a href=\"/broadband/transact-plans.html\">Find out more</a>.";
                }
                message = "<em>Your Exchange</em>: " + exch.name + "<br /><br />" + message + transACT;

            }
            else {
                message = options.messages.dialup;
            }
        }
        else if (resp.reason == "noexchange") {
            message = options.messages.dialup;
        }
        else if (resp.reason == "badnumber") {
            message = options.messages.badnumber;
        }

        /* Well, thank $DEITY that's done with. Now we just have to prod Signup
         * to remember the phone number that was given so the user doesn't have
         * to retype it. */
        if (message != options.messages.badnumber && message != options.messages.error) {
            var phone;
            if (resp.service) {
                phone = resp.service.pstn;
            }
            else {
                phone = $(".area_code", numberChecker).val() + $(".prefix", numberChecker).val() + $(".number", numberChecker).val();
            }
            /* This is cross-domain, so the IFRAME approach is the path of
             * least resistance. In the longer term, it would be nice if
             * refer.cgi was able to send back a JSONP response or something.
             */
            $("iframe", numberChecker).attr("src", options.refer + "?web_pstn=" + phone + "&url=" + options.referDestination);
        }

        displayResult(message);
        
        /* If the page asked for notification when the number checker was done,
         * call it here. */
        if (options.callback) {
            options.callback();
        }
    };

    /**
     * Submit handler for the number checker form. This fires off a query to
     * the number checker backend.
     *
     * @return {Boolean} False to avoid further form processing.
     */
    var onSubmit = function() {
        var phone = $(".area_code", this).attr("value") + $(".prefix", this).attr("value") + $(".number", this).attr("value");
        phone = phone.replace(/[^0-9]/g, "");

        if (phone.search(/^[0-9]{10}$/) == -1) {
            displayResult(options.messages.badnumber);
        }
        else {
            var params = {
                type: "JSON",
                check: "EXCH",
                area: $(".area_code", this).attr("value"),
                prefix: $(".prefix", this).attr("value"),
                number: $(".number", this).attr("value")
            };

            displayThrobber();            
            $.getJSON(options.backend, params, onResponse);
        }
        
        return false;
    };

    /**
     * Handler for the "Try Another Number" link, which basically just fades
     * the form back in.
     *
     * @return {Boolean} False to stop the link being navigated to.
     */
    var onTryAgain = function() {
        $(".result", numberChecker).fadeOut(options.transitionSpeed, function() {
            $("form", numberChecker).fadeIn(options.transitionSpeed);
        });

        return false;
    };

    /* Actually pull in the number checker form template and replace the
     * current element with it. */
    this.load(options.template, null, function() {
        // Set up the onsubmit handler.
        $("form", this).submit(onSubmit);
    });

    return this;
};

// vim: set et ts=4 sw=4 cin nopaste:
