﻿function ResidentialPlanParameters(onNetwork, websurfing, email, gaming, video, downloadSongs, downloadMovies, downloadGames, computers, users) {
    this.onNetwork = onNetwork; 
    this.websurfing = websurfing;
    this.email = email;
    this.gaming = gaming;
    this.video = video;

    this.downloadSongs = downloadSongs;
    this.downloadMovies = downloadMovies;
    this.downloadGames = downloadGames;
    this.computers = computers;
    this.users = users;    
}

function BusinessPlanParameters(onNetwork, websurfing, email, video, files, softwareUpdates, staff, videoConferencing, hosting) {
    this.onNetwork = onNetwork;
    this.email = email;
    this.websurfing = websurfing;
    this.video = video;

    this.files = files;
    this.softwareUpdates = softwareUpdates;
    this.staff = staff;
    this.videoConferencing = videoConferencing;
    this.hosting = hosting;
}

function TelephoneNumberComms(areaCode, prefix, phoneNumber) {
    this.areaCode = areaCode;
    this.prefix = prefix;
    this.phoneNumber = phoneNumber;

    this.GetQueryString = function() {
        return "phonenumber=" + this.areaCode + this.prefix + this.phoneNumber;
    }
}

function PostCodeComms(postCode) {
    this.postCode = postCode;

    this.GetQueryString = function() {
        return "postcode=" + this.postCode;
    }
}

function EmptyComms() {
    this.GetQueryString() = function() {
        return "";
    }
}

//class to manage the interaction with the Plan Selector Service and marshall the callback
function PlanSelector(config) {
    this.config = config;

    this.SelectBusinessPlans = function(params, commsType, callBack) {
        var planSelectorUrl = BuildBusinessPlanSelectionUrl(this.config, commsType, params);

        $.getJSON(planSelectorUrl,
                    function(data) {
                        var psLogic = new PlanSelectorLogic(data.plans, params.onNetwork, true);
                        callBack(psLogic);
                    });
                }

   this.SelectResidentialPlans = function(params, commsType, callBack) {
        var planSelectorUrl = BuildPlanSelectorUrl(this.config, commsType, params);

        $.getJSON(planSelectorUrl,
                    function(data) {
                        var psLogic = new PlanSelectorLogic(data.plans, params.onNetwork, false);
                        callBack(psLogic);
                    });
                }

    function BuildPlanSelectorUrl(config, commsType, params) {

        return config.planSelectorUrl +
                    "?class=residential" +
                    "&" + commsType.GetQueryString() +
                    "&onnet=" + GetOnPlanQSValue(params.onNetwork) +
                    "&email=" + params.email +
                    "&websurfing=" + params.websurfing +
                    "&chat=1" +
                    "&gaming=" + params.gaming +
                    "&streaming=" + params.video +
                    "&downloads=" + params.downloadMovies +
                    "&users=" + params.users +
                    "&computers=" + params.computers +
                    "&naked=1";                    
    }

    function BuildBusinessPlanSelectionUrl(config, commsType, params) {

        return config.planSelectorUrl +
                    "?class=business" +
                    "&" + commsType.GetQueryString() +
                    "&onnet=" + GetOnPlanQSValue(params.onNetwork) +
                    "&email=" + params.email +
                    "&websurfing=" + params.websurfing +
                    "&attachments=" + params.files +
                    "&streaming=" + params.video +
                    "&downloads=" + params.softwareUpdates +
                    "&videoconferencing=" + params.videoConferencing +
                    "&users=" + params.staff +
                    "&hosting=" + params.hosting +
                    "&naked=1";
    }

    function GetOnPlanQSValue(onNetwork) {
        if (onNetwork) {
            return "1";
        } else {
            return "0";
        }
    }
}


//class to handle the logic for which plans are presented to the user
//todo - separate selector logic for business/residential
function PlanSelectorLogic(rawResult, onNetwork, businessPlans) {
    this.onNetwork = onNetwork;
    this.rawResult = rawResult;
    this.businessPlans = businessPlans;

    this.recommendedPlan = GetRecommendedPlan(rawResult, this.onNetwork, businessPlans);
    this.otherPlans = GetOtherPlans(rawResult, this.onNetwork, businessPlans);

    function GetRecommendedPlan(rawResult, onNetwork, businessPlans) {
        var recommendedPlan;

        if (onNetwork) {
            if (businessPlans) {
                //business plans should show the bundled standard plan as priority
                recommendedPlan = FindBundledPlansByNetwork(rawResult, 'iislam')[0];
            } else {
                //assume there's a ULL (naked plan)
                recommendedPlan = FindPlanByNetwork(rawResult, 'ull');
            }
        } else {
            //assume telstra bundled is priority off-network
            recommendedPlan = FindBundledPlansByNetwork(rawResult, 'telstra')[0];
        }

        return new PlanDisplayer(recommendedPlan, businessPlans);
    };

    function GetOtherPlans(rawResult, onNetwork, businessPlans) {
        var otherPlans = new Array();

        otherPlans[0] = GetFirstOption(rawResult, onNetwork, businessPlans);

        //only on network should have a second option
        if (onNetwork)
            otherPlans[1] = GetSecondOption(rawResult, onNetwork, businessPlans);

        return otherPlans;
    }

    function GetFirstOption(rawResult, onNetwork, businessPlans) {
        var recommendedPlan;

        if (onNetwork) {
            if (businessPlans) {
                //first option should be unbundled for business
                recommendedPlan = FindUnbundledPlansByNetwork(rawResult, 'iislam')[0];
            } else {
                recommendedPlan = FindBundledPlansByNetwork(rawResult, 'iislam')[0];
            }
        } else {
            recommendedPlan = FindUnbundledPlansByNetwork(rawResult, 'telstra')[0];
        }

        return new PlanDisplayer(recommendedPlan, businessPlans);
    }


    function GetSecondOption(rawResult, onNetwork, businessPlans) {
        var recommendedPlan;

        if (onNetwork) {
            if (businessPlans) {
                //naked should be the third option for business
                recommendedPlan = FindPlanByNetwork(rawResult, 'ull');
            } else {
                recommendedPlan = FindUnbundledPlansByNetwork(rawResult, 'iislam')[0];
            }
            //assume there's 2 returned

        } else {
            //there is no 2nd option for off network
            return null;
        }

        return new PlanDisplayer(recommendedPlan, businessPlans);
    }

    function FindPlanByNetwork(plans, networkName) {
        var foundPlan;

        for (i = 0; i < plans.length; i++) {
            if (plans[i].Network == networkName)
                return plans[i];
        }
    };

    function FindBundledPlansByNetwork(plans, networkName) {
        return FindBundledPlans(FindPlansByNetwork(plans, networkName));
    }

    function FindUnbundledPlansByNetwork(plans, networkName) {
        return FindUnbundledPlans(FindPlansByNetwork(plans, networkName));
    }

    function FindPlansByNetwork(plans, networkName) {
        var foundPlans = new Array();
        var foundIndx = 0;

        for (i = 0; i < plans.length; i++) {
            if (plans[i].Network == networkName) {
                foundPlans[foundIndx] = plans[i];
                foundIndx++;
            }
        }

        return foundPlans;
    };

    function FindPlansByBundle(plans, bundle) {
        var foundPlans = new Array();
        var foundIndx = 0;

        for (i = 0; i < plans.length; i++) {
            if (plans[i].Bundled == bundle) {
                foundPlans[foundIndx] = plans[i];
                foundIndx++;
            }
        }

        return foundPlans;
    }

    function FindBundledPlans(plans) {
        return FindPlansByBundle(plans, "1");
    };

    function FindUnbundledPlans(plans) {
        return FindPlansByBundle(plans, "0");
    };
}

//class to handle the display characteristics for a plan
//TODO - this is getting out of hand - refactor heavily
function PlanDisplayer(rawPlan, businessPlan) {
    this.rawPlan = rawPlan;
    this.businessPlan = businessPlan;
    this.GetMarketingBlurb = function() {
        var blurb = '';
        //TODO - should be a hashtable or subclasses

        blurb = networkWording[this.rawPlan.Network];

        //naked doesn't have the additional text, bundling is irrelevant
        if (this.rawPlan.Network != 'ull') {
            if (this.IsBundled()) {
                blurb += " with great call rates";
            } else {
                blurb += " that won't break your budget";
            }
        }

        return blurb;
    }

    this.GetPlanCosts = function() {
        //add a zero onto the end of costs that only have one number to the right of the decimal
        var match = /^[0-9]+\.[0-9]$/.test(rawPlan.MonthlyCost);
        
        if(match) {
            return rawPlan.MonthlyCost + '0';
        }
        
        return rawPlan.MonthlyCost;
    }

    this.GetAdditionalCosts = function() {
        if (this.IsBundled()) {
            if (this.IsBusinessPlan()) {
                //bundled business plans have a line rental cost
                return '35.95';
            } else {
                //bundled residential plans have a line rental cost too
                return '29.95';
            }
        } else {
            return '';
        }
    }

    this.IsBusinessPlan = function() {
        return this.businessPlan;
    }

    this.GetMinorBlurb = function() {
        if (this.rawPlan.Network == 'ull')
            return 'Free local & national calls; No line rental.';

        //todo - inject plan wording
        return planWording[this.rawPlan.PlanName];
    }

    function GetLastChars(planName, numberOfChars) {
        return planName.substring(planName.length - numberOfChars, planName.length);
    }

    this.IsBundled = function() {
        return this.rawPlan.Bundled == "1";
    }

    this.GetPlanName = function() {
        if (this.IsBundled()) {
            return 'Bundled ' + this.rawPlan.PlanName;
        } else {
            return this.rawPlan.PlanName;
        }
    }

    this.GetSpeed = function() {
        if(this.rawPlan.Network == 'telstra') {
            switch (this.rawPlan.Speed) {
                case '24000':
                    return 'up to 24Mbps';
                case '8000':
                    return 'up to 8Mbps';
                case '1500':
                    return '1.5Mbps';
                case '256':
                    return '256Kbps';
            }
        }
        else {
            switch (this.rawPlan.Speed) {
                case '24000':
                    return 'ADSL2+';
                case '8000':
                    return 'ADSL2+';
                case '1500':
                    return 'ADSL2+';
                case '256':
                    return '256KBPS';
            }
        }
    }

    this.GetTotalQuota = function() {
        return this.rawPlan.TotalQuota + 'GB';
    }

    this.GetPeak = function() {
        return this.rawPlan.OnPeakQuota + 'GB';
    }

    this.GetOffPeak = function() {
        return this.rawPlan.OffPeakQuota + 'GB';
    }

    this.GetSignUpUrl = function() {
        return this.rawPlan.SignupUrl;
    }
} 
