/**
 * @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>iiNetwork ADSL2+ 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>iiNetwork ADSL2+ 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 iiNetwork ADSL2+ 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>Off-Net ADSL1 &amp; 2+</strong> options shown below.",
            offnet: "The telephone number you supplied supports a <strong>Off-Net ADSL1 &amp; 2+</strong> connection with speeds up to 20/1Mbps. Please choose from one of the Off-Net ADSL1 &amp; 2+ plan options shown below.",
            transit_some: "Your area is scheduled for an upgrade to iiNetwork ADSL2+ in the near future. While you wait for iiNetwork ADSL2+ to arrive, we have an exclusive set of plans called <strong>Off-Net ADSL1 &amp; 2+ 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 iiNetwork ADSL2+ in the near future. While you wait for iiNetwork ADSL2+ to arrive, we have an exclusive set of plans called <strong>Off-Net ADSL1 &amp; 2+ 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>Off-Net ADSL1 &amp; 2+</strong> connection with speeds up to 20/1Mbps. Please choose from one of the Off-Net ADSL1 &amp; 2+ plan options shown below.",
            onnet_none_transit_some: "Your area is scheduled for an upgrade to iiNetwork ADSL2+ in the near future. While you wait for iiNetwork ADSL2+ to arrive, we have an exclusive set of plans called <strong>Off-Net ADSL1 &amp; 2+ transit</strong> available to you. <a href='/broadband/transit-plans.html'>Find out more about Off-Net ADSL1 &amp; 2+ transit plans.</a>",
            onnet_none_transit_afew: "Your area is scheduled for an upgrade to iiNetwork ADSL2+ in the near future. While you wait for iiNetwork ADSL2+ to arrive, we have an exclusive set of plans called <strong>Off-Net ADSL1 &amp; 2+ 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 iiNetwork ADSL2+ 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>Off-Net ADSL1 &amp; 2+</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>Off-Net ADSL1 &amp; 2+</strong> connection of up to 8,000kbps. Choose from one of our <a href='/broadband/plans.html'>Off-Net ADSL1 &amp; 2+ 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 iiNetwork ADSL2+ 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>Off-Net ADSL1 &amp; 2+</strong> connection of up to 8,000kbps. Choose from one of our <a href='/broadband/plans.html'>Off-Net ADSL1 &amp; 2+ plans</a>. Learn more about <a href='https://iihelp.iinet.net.au/Broadband_availability'>iiNetwork ADSL2+ port availability</a>",
            onnet_none_transit_afew_naked: "Your area is scheduled for an upgrade to iiNetwork ADSL2+ in the near future. While you wait for iiNetwork ADSL2+ to arrive, we have an exclusive set of plans called <strong>Off-Net ADSL1 &amp; 2+ transit</strong>. Learn more about <a href='/broadband/transit-plans.html'>Off-Net ADSL1 &amp; 2+ transit plans</a>",
            onnet_none_transit_none_naked: "There are currently no iiNetwork ADSL2+ 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>Off-Net ADSL1 &amp; 2+</strong> connection of up to 8,000kbps. Choose from one of our <a href='/broadband/plans.html'>Off-Net ADSL1 &amp; 2+ plans</a> or learn more about <a href='https://iihelp.iinet.net.au/Broadband_availability'>iiNetwork ADSL2+ port availability</a>."
        },
        override: {},
        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",
        ticker: "/img/Throbber-mac.gif",
        popup: false
    };
    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) {
        if (options.popup) {
            $("form", numberChecker).show();
            $(".throbber", numberChecker).remove();
            $(".message", numberChecker).html(message);
            $(".try_again", numberChecker).click(onTryAgain);
            $.fancybox($(".result").html(), { 
				'width'				: '75%',
				'height'			: '75%',
				'autoScale'			: false,
				'transitionIn'		: 'none',
				'transitionOut'		: 'none'
            });
        }
        else {
            $("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() {
        if (options.popup)
            $("form", numberChecker).hide();
        $("form", numberChecker).after("<img class='throbber' src='" + options.ticker + "' 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 key = null;
        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":
                            key = 'onnet_some';
                            if ($.profile)
                                $.profile("plan", { iinet: true, holding: false });
                            break;
                        case "afew":
                            key = 'onnet_afew';
                            if ($.profile)
                                $.profile("plan", { iinet: true, holding: false });
                            break;
                        case "none":
                            if (holding) {
                                if (is_naked()) {
                                    switch (holding) {
                                        case "some":
                                            key = 'onnet_none_transit_some';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "afew":
                                            key = 'onnet_none_transit_afew_naked';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "none":
                                            key = 'onnet_none_transit_none_naked';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: false });
                                            break;
                                        default:
                                            key = 'onnet_none_naked';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: false });
                                    }
                                }
                                else {
                                    switch (holding) {
                                        case "some":
                                            key = 'onnet_none_transit_some';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "afew":
                                            key = 'onnet_none_transit_afew';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: true });
                                            break;
                                        case "none":
                                            key = 'onnet_none_transit_none';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: false });
                                            break;
                                        default:
                                            key = 'onnet_none';
                                            if ($.profile)
                                                $.profile("plan", { iinet: false, holding: false });
                                    }
                                }
                            }
                            else {
                                if (is_naked())
                                    key = 'offnet_naked';
                                else
                                    key = 'offnet';
                                if ($.profile)
                                    $.profile("plan", { iinet: false, holding: false });
                            }
                    }
                }

                if (!key && holding) {
                    switch (holding) {
                        case "some":
                            key = 'transit_some';
                            if ($.profile)
                                $.profile("plan", { iinet: false, holding: true });
                            break;
                        case "afew":
                            key = 'transit_afew';
                            if ($.profile)
                                $.profile("plan", { iinet: false, holding: true });
                            break;
                        case "none":
                            key = 'transit_none';
                            if ($.profile)
                                $.profile("plan", { iinet: false, holding: false });
                            break;
                        default:
                            if (is_naked())
                                key = 'offnet_naked';
                            else
                                key = 'offnet';
                            if ($.profile)
                                $.profile("plan", { iinet: false, holding: false });
                    }
                }
                
                if (!key) {
                    key = 'offnet';
                    if ($.profile)
                        $.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 = options.messages[key];
                if (options.override[key]) message = options.override[key];
                message = "<em>Your Exchange</em>: " + exch.name + "<br /><br />" + message + transACT;

            }
            else {
                key = 'dialup';
            }
        }
        else if (resp.reason == "noexchange") {
            key = 'dialup';
			if ($.profile)
				$.profile("plan", { iinet: false, holding: false, bad: true });
        }
        else if (resp.reason == "badnumber") {
            key = 'badnumber';
			if ($.profile)
				$.profile("plan", { iinet: false, holding: false, bad: true });
        }

        /* 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 (key != 'badnumber' && key != '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);
        }

        // If no message at this point, create it.
        if (!message) {
            message = options.messages[key];
            if (options.override[key]) message = options.override[key];
        }
        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) {
            var message = options.messages.badnumber;
            if (options.override.badnumber) message = options.override.badnumber;
            displayResult(message);
        }
        else {
            var params = {
                type: "JSON",
                check: "EXCH",
                area: $(".area_code", this).attr("value"),
                prefix: $(".prefix", this).attr("value"),
                number: $(".number", this).attr("value")
            };

            displayThrobber();            
            var url = options.backend + "?nocache=1";
            var key = "";
            for (key in params) {
                url += "&" + key + "=" + params[key];
            }
            url += "&jsoncallback=?";
            $.getJSON(url, 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:

