﻿/// <reference path="lib_core.js"/>
/// <reference path="lib_core_controls.js"/>
/// <reference path="lib_fieldeditors.js"/>
/// <reference path="lib.js"/>
/// <reference path="join.js"/>

// Give this a default tariff?

// Important bit of the join process, will use data provided by the server.

RegisterBox.LandlineSelector = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = RegisterBox.LandlineSelector.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('LandlineSelector');
    var rmbItems = new Array();
    rmbItems.push(new AOption({'text':'Line Rental:', 'value':'0', 'selected':true, 'price':9.99, 'questionMarkText': 'Analogue Line Rental for only £9.99 a month'}));
    var o = new Object();
    o.buttonSide = 'right';
    this.rbmLandline = new RadioButtonMenu(this, o, rmbItems);
    //this.rbmLandline.setSelectedByValue('0');
    this.rbmLandline.render();
    this.addMyEl();
}

var paperBillingChoices = new Object();
paperBillingChoices[0] = {'name': 'Web billing', 'price': 0};
paperBillingChoices[1] = {'name': 'Paper billing', 'price': 2.95};

RegisterBox.PaperBillingChoice = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = RegisterBox.PaperBillingChoice.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('PaperBillingChoice');
    this.csBillingChoice = new CSpan(this);
    this.csBillingChoice.setClass('title');
    //this.csSelectTariff.setInnerHTML('Please select your tariff');
    this.csBillingChoice.setInnerHTML('Select your billing method');
    
    
    var rmbItems = new Array();
    this.rmbItems = rmbItems;
    
    // These AOptions could do with a way of putting a question mark description on them.
    
    //for (var c = 0; c < tariffs.length; c++) {
        //alert ('tariffs[c].questionMarkText ' + tariffs[c].questionMarkText);
    //    rmbItems.push(new AOption({'text':tariffs[c].name + ':', 'value':c, 'price':tariffs[c].price, 'questionMarkText': tariffs[c].questionMarkText}));
    //}
    rmbItems.push(new AOption({'text': 'Web billing:', 'value': 0, 'price': 0, 'questionMarkText': 'Web billing is free helps the environment'}));
    rmbItems.push(new AOption({'text': 'Paper billing:', 'value': 1, 'price': 2.95, 'questionMarkText': 'Paper bills cost £2.95 a month'}));
    
    
    rmbItems[0].options.selected = true;
    var o = new Object();
    o.buttonSide = 'right';
    
    this.paperBillingChoice = paperBillingChoices[0];
    
    // the RadioButtonMenu needs to include the price - the radio button is in the middle like with CheckBoxMenu.
     
    this.rbmBillingMethods = new RadioButtonMenu(this, o, rmbItems);
    //this.rbmTariffs.setSelectedByValue(0);
    this.rbmBillingMethods.render();
    
    // need to avoid the standard click event.
    // It may be better to use another event name, like itemchosen.
    
    this.rbmBillingMethods.onclick = function(text, value) {
        if (text) return this.container.rbmBillingMethods_onclick(text, value);
        
    };
    
    this.tariff = tariffs[0];
    // and select the 'Pay As You Go' tariff from the radio list.
    var cdc = new CDClear(this);
    
    this.addMyEl();
}
p.rbmBillingMethods_onclick = function(text, value) {
    //this.tariff = tariffs[value];
    //if (this.tariff_selected) this.tariff_selected(this.tariff);
    this.paperBillingChoice = paperBillingChoices[value];
    if (this.onchange) this.onchange();
}
p.setValue = function(/*paperBillingChoice*/ value) {
    // need to look at the items in the RadioButtonMenu?
    
    var index;
    for (var c = 0; c < 4; c++) {
        var i = paperBillingChoices[c];
        if (i == value) {
            index = c;
        }
    }
    //alert('index ' + index);
    if (index) {
        this.rbmBillingMethods.setSelectedByValue(index);
        this.rbmBillingMethods.render();
        return true;
    }
    
    
}

RegisterBox.TariffSelector = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = RegisterBox.TariffSelector.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('TariffSelector');
    // though could use a groupName if one was given in the options - allow it to be specified, but otherwise generate one.
    
    this.groupName = UID();
    this.csSelectTariff = new CSpan(this);
    this.csSelectTariff.setClass('title');
    //this.csSelectTariff.setInnerHTML('Please select your tariff');
    this.csSelectTariff.setInnerHTML('Select your call tariff');
    
    // will build a more advanced validation system.
    
    //this.csValidationError = new CSpan(this);
    //this.csValidationError.setInnerHTML('*');
    //this.csValidationError.setClass('validationFailure');
    //this.csValidationError.hide();
    
    var rmbItems = new Array();
    this.rmbItems = rmbItems;
    
    // These AOptions could do with a way of putting a question mark description on them.
    
    for (var c = 0; c < tariffs.length; c++) {
        //alert ('tariffs[c].questionMarkText ' + tariffs[c].questionMarkText);
        rmbItems.push(new AOption({'text':tariffs[c].name + ':', 'value':c, 'price':tariffs[c].price, 'questionMarkText': tariffs[c].questionMarkText}));
    }
    rmbItems[0].options.selected = true;
    var o = new Object();
    o.buttonSide = 'right';
    
    // the RadioButtonMenu needs to include the price - the radio button is in the middle like with CheckBoxMenu.
     
    this.rbmTariffs = new RadioButtonMenu(this, o, rmbItems);
    //this.rbmTariffs.setSelectedByValue(0);
    this.rbmTariffs.render();
    
    // need to avoid this getting called twice?
    // once by specialized mechanism to deal with processing the menu item clicks,
    // another for the CDiv that was clicked in.
    
    this.rbmTariffs.onclick = function(text, value){
        //alert('this.rbmTariffs.onclick');
//        if (text && value) {
//            text.nkjnbjk.dasfasf.fdsaf;
//        }
        if (text) return this.container.rbmTariffs_onclick(text, value);
        
    };
    this.tariff = tariffs[0];
    // and select the 'Pay As You Go' tariff from the radio list.
    
    var cdc = new CDClear(this);
    
    this.addMyEl();
}
p.clear = function() {
    //alert('begin TariffSelector clear');
    
//    this.rbmTariffs.clear();
//    this.rmbItems[0].options.selected = true;
//    for (var c = 1; c < this.rmbItems.length; c++) {
//        this.rmbItems[c].options.selected = false;
//    }
//    this.rbmTariffs.render();
    this.tariff = tariffs[0];
    this.setValue(tariffs[0]);
    
    //alert('end TariffSelector clear');
    // select the default value.
    
}
p.rbmTariffs_onclick = function(text, value) {
    //alert('rbmTariffs_onclick');
    // maybe should not use 'this.tariff', could use 'getTariff';
    
    this.tariff = tariffs[value];
    
    //alert('value ' + value);
    //alert('this.tariff ' + this.tariff);
    
    //alert('value ' + value);
    
    if (this.tariff_selected) this.tariff_selected(this.tariff);
    if (this.onchange) this.onchange();
}
p.validate = function() {
    // be careful it does not validate and show an error as it is created.
    
    // will use ValidationResult objects.
    
    // probably will always be valid.
    
    var isValid = this.isValid();
//    if (res) {
//        this.csValidationError.hide();
//    } else {
//        this.csValidationError.show();
//    }
    return new ValidationResult({'isValid':isValid});
}
p.isValid = function() {
    // now using the RadioButtonMenu - that needs a way of checking if any of them have been selected.
    return this.rbmTariffs.validateItemSelected();
}
p.trb_select = function(trb) {
    this.tariff = trb.tariff;
}
p.setValue = function(/* tariff */ value) {
    // need to select the correct option in the RadioButtonMenu
    // the tariff should have an index.
    // but find the tariff's index.
    
    // or is there a better way of doing this?
    
    //alert ('value ' + value);
    
    
    var index;
    for (var c = 0; c < 4; c++) {
        var i = tariffs[c];
        if (i == value) {
            index = c;
        }
    }
    
    //alert('setValue index ' + index);
    if (index || index === 0) {
        this.rbmTariffs.setSelectedByValue(index);
        this.rbmTariffs.render();
        return true;
    }
    
}


var phoneNumbers = new Array();
var phoneNumberIndex = 1;

// Perhaps the correct numbers could be compiled into a list for the later stage.

// There (I think) will only be one removed number.
var removedPhoneNumber;
removeEmptyPhoneNumbers = function() {
    //alert('removeEmptyPhoneNumbers');
    var c = 1;
    while(phoneNumbers[c]) {
        phoneNumberIndex = c;
        //alert('c ' + c + ', phoneNumbers[c].options.landlineNumber.length ' + phoneNumbers[c].options.landlineNumber.length);
        if (phoneNumbers[c].options.landlineNumber.length === 0) {
            removedPhoneNumber = phoneNumbers[c]
            //alert('phoneNumbers.length ' + phoneNumbers.length);
            phoneNumbers.splice(c, 1);
            //alert('phoneNumbers.length ' + phoneNumbers.length);
            
            c--;
        }
        c++;
    }
    
}

getFreePhoneNumberIndex = function() {
    // this will need to be done because items may be deleted, and it needs to go through
    // the phone numbers, finding the free one.
    
    // maybe it should also look for an empty item
    
    var res = 1;
    while(phoneNumbers[res]) {
        // check to see if the one found is empty.
        // the landline number?
        //alert ('phoneNumbers[res].options.landlineNumber ' + phoneNumbers[res].options.landlineNumber);
        
        if (phoneNumbers[res].options.landlineNumber.length === 0) {
            return res;
        }
        
        res++;
        
        
    }
    return res;
}

//addPhoneNumber = function(value) {
//    value.options.index = phoneNumberIndex;
//    phoneNumbers[phoneNumberIndex] = value;
//    phoneNumberIndex++;
//    updateOrderSummary(value);
//}

updateOrderSummary = function(currentNumber) {
    orderSummary.update(currentNumber);
}

// Probably no need to use the NumberEntry Summary - 
// use the OrderSummary to show the current number being entered.

var numberEntry;

// New version of this control will be used to enter a phone number.

// Are the add-ons different for residential or business?
//  How to denote limited add-on availability?

RegisterBox.NumberEntry = function(container) {
    this.container = container;
    this.init(0);
}
var p = RegisterBox.NumberEntry.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    numberEntry = this;
    
    this.superInit(depth);
    this.setClass('NumberEntry');
    
    var cbr = new CBr(this);
    cbr.setStyle('clear', 'both');
    
    //this.cdhNumberN = new CDiv(this, {'cssClass': 'title'});
    //this.cdhNumberN.setInnerHTML('Telephone number 1');
    
    this.cdLeft = new CDiv(this, {'cssClass': 'NumberEntry_cdLeft'})
    this.cdRight = new CDiv(this, {'cssClass': 'NumberEntry_cdRight'})
    
    this.ukLandlineNumberField = new UKLandlineNumberField(this.cdLeft);
    var o = new Object();
    o.min = 1;
    o.max = 10;
    o.labelText = 'No. of lines for this number:';
    o.labelWidth = 251;
    //o.fieldWidth = 62;
    var cbr = new CBr(this);
    cbr.setStyle('clear', 'both');
    
    //this.ukLandlineNumberField.onchange = function() {this.container.container.ukLandlineNumberField_onchange();}
    //this.ukLandlineNumberField.onkeypress = function() {this.container.container.ukLandlineNumberField_onkeypress();}
    this.ukLandlineNumberField.onkeyup = function() {this.container.container.ukLandlineNumberField_onkeyup();}
    
    // need to avois an additional left margin.
    this.fflmfNumberOfPhoneLines = new DropDownListWithMoreField(this.cdLeft, o);
    this.fflmfNumberOfPhoneLines.onchange = function() { this.container.container.fflmfNumberOfPhoneLines_onchange(); return false; }
    
    this.landlineSelector = new RegisterBox.LandlineSelector(this.cdLeft);
    
    this.tariffSelector = new RegisterBox.TariffSelector(this.cdLeft);
    this.tariffSelector.onchange = function() { this.container.container.tariffSelector_onchange(); return false; }
    var aoo = new Array();
    
    for (var c = 0; c < addOns.length; c++) {
        var aoAddOn = new AOption(addOns[c].name, addOns[c].id
         );
        aoo.push(aoAddOn);
    }
    
    // then there is the selector for the paper billing question.
    
    this.paperBillingChoice = new RegisterBox.PaperBillingChoice(this);
    this.paperBillingChoice.onchange = function() { this.container.paperBillingChoice_onchange(); return false; }
    
    this.addOnsSelector = new RegisterBox.AddOnsSelector(this.cdLeft)
    this.addOnsSelector.onchange = function() { this.container.container.addOnsSelector_onchange(); return false; }
    
    var number = this.getPhoneNumber();
    
    //this.numberEntrySummary = new NumberEntrySummary(this.cdRight);
    //this.numberEntrySummary.setNumber(number);
    
    // The order summary will also need the number being entered.
    this.orderSummary = new OrderSummary(this.cdRight);
    var that = this;
    // when someone edits a number it needs to call a function.
    this.orderSummary.oneditnumber = function(numberIndex) {
        //alert('this.orderSummary.oneditnumber phoneNumberIndex: ' + phoneNumberIndex + ', numberIndex: ' + numberIndex);
        // save the current number
        // is saving the current number necessary?
        
        //that.saveCurrentNumber();
        
        // then set the values in the editor to the values of that number
        that.editPhoneNumberByIndex(numberIndex);
    }
    
    // also on the right we want a button for adding another phone number.
    // for the moment I can simply use a CDiv for this and style that CDiv.
    
    
    
    //this.orderSummary.hide();
    var ca = new CDClear(this);
    
    this.addMyEl();
}

p.editPhoneNumberByIndex = function(numberIndex) {
    var num = phoneNumbers[numberIndex];
    phoneNumberIndex = numberIndex;
    
    // will need to tell the NumbersEntry this this is being edited.
    if (this.oneditphonenumber) this.oneditphonenumber(num);
    
    this.ukLandlineNumberField.setValue(num.options.landlineNumber);
    this.fflmfNumberOfPhoneLines.setValue(num.options.numLines);
    
    //alert('setting tariff');
    //alert('num.options.tariff ' + num.options.tariff);
    //alert('num.options.tariff.options.id ' + num.options.tariff.id);
    //alert('num.options.index ' + num.options.index);
    this.tariffSelector.setValue(num.options.tariff);
    //alert('has set tariff');
    this.addOnsSelector.setSelectedValues(num.options.addOns);
    this.paperBillingChoice.setValue(num.options.paperBillingChoice);
    
    updateOrderSummary(phoneNumbers[phoneNumberIndex]);
}

p.saveCurrentNumber = function() {
    //alert ('save current number');
    phoneNumbers[phoneNumberIndex] = this.getPhoneNumber();
    
}

p.validatePhoneNumber = function() {
    // get the phone number
    
    // does it pass a regular expression?
    
}

p.isPhoneNumberValid = function() {
    var res = this.ukLandlineNumberField.isValid();
    //alert('isPhoneNumberValid res ' + res);
    return res;
}

p.ukLandlineNumberField_onchange = function() {
    //alert ('ukLandlineNumberField_onchange');
    //this.updateOrderSummary();
}
p.ukLandlineNumberField_onkeypress = function() {
    //alert ('ukLandlineNumberField_onchange');
    //this.updateOrderSummary();
}
p.ukLandlineNumberField_onkeyup = function() {
    //alert ('ukLandlineNumberField_onchange');
    this.updateOrderSummary();
}

p.clear = function() {
    //alert ('RegisterBox.NumberEntry clear');
    this.fflmfNumberOfPhoneLines.clear();
    this.ukLandlineNumberField.clear();
    this.tariffSelector.clear();
    this.addOnsSelector.clear();
    //this.numberEntrySummary.clear();
    var number = this.getPhoneNumber();
    //this.numberEntrySummary = new NumberEntrySummary(this.cdRight);
    
    // set to pay as you go
    
    //this.numberEntrySummary.setNumber(number);
    
}

// Also need to update the number entry summary when other things including the payment method are changed.
// This change takes place in the payment summary page.

//p.updateNumberEntrySummary = function() {
//    this.numberEntrySummary.setNumber(this.getPhoneNumber());
//}

p.updateOrderSummary = function() {
    //alert('p.updateOrderSummary');
    var num = this.getPhoneNumber()
    if (!phoneNumbers[phoneNumberIndex]) phoneNumbers[phoneNumberIndex] = num;
    
    updateOrderSummary(num);
}

p.paperBillingChoice_onchange = function() {
    //alert('paperBillingChoice_onchange');
    //this.updateNumberEntrySummary();
    this.updateOrderSummary();
}

p.fflmfNumberOfPhoneLines_onchange = function() {
    this.updateOrderSummary();
    //this.updateNumberEntrySummary();
}
p.tariffSelector_onchange = function() {
    //this.updateNumberEntrySummary();
    this.updateOrderSummary();
}
p.addOnsSelector_onchange = function() {
    //this.updateNumberEntrySummary();
    this.updateOrderSummary();
    if (this.onchange) this.onchange();
}

p.getPrice = function() {
    // the phone number object returns the price.
    
    var pn = this.getPhoneNumber();
    return pn.getPrice();
    
}

p.getNumberOfLines = function() {
    //alert ('this.ddlNumPhoneNumbers.value ' + this.ddlNumPhoneNumbers.value);
    
    //if (this.ddlNumPhoneNumbers.value
}

p.ddl_onchange = function() {
    if (this.ddlNumPhoneNumbers.value == 'more') {
        this.txtNumPhoneNumbers.show();
        this.txtNumPhoneNumbers.selectAll();
    } else {
        this.txtNumPhoneNumbers.hide();
    }
}

p.isValid = function() {
    var res = true;
    var val;
    val = this.ukLandlineNumberField.isValid();
    //alert('val ' + val);
    if (!val) res = false;
    //val = this.tariffSelector.isValid() && val;
    //if (!val) res = false;
    return res;
}

p.getPhoneNumber = function() {
    // perhaps in the list of phone numbers it already exists.
    // in which case, modify that phone number.
    
    var landlineNumber = this.ukLandlineNumberField.getValue();
    //alert('landlineNumber ' + landlineNumber);
    
    var numberOfPhoneLines = this.fflmfNumberOfPhoneLines.getValue();
    
    //alert('getPhoneNumber numberOfPhoneLines ' + numberOfPhoneLines);
    
    var tariff = this.tariffSelector.tariff;
    // either
    var addOns = this.addOnsSelector.getSelectedValues();
    var paperBillingChoice = this.paperBillingChoice.paperBillingChoice;
    
    var res;
    
    if (phoneNumbers[phoneNumberIndex]) {
        //alert ('found');
        res = phoneNumbers[phoneNumberIndex];
        res.options.landlineNumber = landlineNumber;
        res.options.numLines = numberOfPhoneLines;
        res.options.tariff = tariff;
        res.options.addOns = addOns;
        res.options.paperBillingChoice = paperBillingChoice;
    } else {
        //alert('not found');
        res = new Order.PhoneNumber({'landlineNumber': landlineNumber, 'numLines': numberOfPhoneLines, 'tariff': tariff, 'addOns': addOns, 'paperBillingChoice': paperBillingChoice});;
    }
    
    //alert('paperBillingChoice ' + paperBillingChoice);
    return res;
}

// For entering more than one number.
//  Co-ordinates entering numbers.

RegisterBox.NumbersEntry = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = RegisterBox.NumbersEntry.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('NumbersEntry');
    
    this.completedNumbers = new RegisterBox.NumbersDisplay(this);
    this.completedNumbers.setFloat('left');
    
    this.cdc1 = new CDClear(this);
    
    // needs to say what number is being entered.
    
    //this.numberN = 1;
    
    this.cdhNumberN = new CDiv(this, {'cssClass': 'title'});
    this.cdhNumberN.setInnerHTML('Telephone number ' + phoneNumberIndex);
    
    this.numberEntry = new RegisterBox.NumberEntry(this);
    this.numberEntry.oncomplete = function(obj) {this.container.numberEntry_complete(obj); return false};
    var that = this;
    this.numberEntry.oneditphonenumber = function(phoneNumber) {
        //alert('phoneNumber.options.index ' + phoneNumber.options.index);
        phoneNumberIndex = phoneNumber.options.index;
        that.updateNumberTitle();
        
        // or the numberEntry can handle the changes.
        // need to get the values into the input controls.
        
    }
    
    //this.cdEnterAnotherNumberQuestion = new CDiv(this);
    //this.cdEnterAnotherNumberQuestion.setClass('cdEnterAnotherNumberQuestion');
    //this.cdEnterAnotherNumberQuestion.hide();
    //this.ynrfAnotherNumber = new YesNoRadioField(this.cdEnterAnotherNumberQuestion, {'labelText': 'Do you want to add another phone number?'});
    //this.btnAnotherNumberProceed = new CButton(this.cdEnterAnotherNumberQuestion, 'OK');
    //this.btnAnotherNumberProceed.onclick = function() { this.container.container.btnAnotherNumberProceed_onclick(); return false; }

    //this.btnAddPhoneNumber = new BoldButton(this, { 'text': 'Add another phone number', 'buttonColor': 'blue' });
    this.btnAddPhoneNumber = new ImageButton(this, { 'src': '/images/btn-add-another-phone-numbe.gif'});
    this.btnAddPhoneNumber.onclick = function() { this.container.btnAddPhoneNumber_onclick(); return false; }
    this.btnAddPhoneNumber.setClass('btnAddAnotherNumber');
    
    this.numberEntry.updateOrderSummary();
    
    this.addMyDiv();
}

p.updateNumberTitle = function() {
    this.cdhNumberN.setInnerHTML('Telephone number ' + phoneNumberIndex);
}
//p.btnAnotherNumberProceed_onclick = function() {
//    var phoneNumber = this.numberEntry.getPhoneNumber();
//    var another = this.ynrfAnotherNumber.getValue()
//    //alert ('another ' + another);
//    
//    if (another) {
//        this.numberEntry.clear();
//        this.numberEntry.show();
//        this.btnAddPhoneNumber.show();
//        this.cdEnterAnotherNumberQuestion.hide();
//        
//    } else {
//        // move onto the payment details
//        
//        if (this.oncomplete) this.oncomplete();
//    }
//    
//}

// Need to validate the current phone number before adding it.

p.validatePhoneNumber = function() {
    return this.numberEntry.validatePhoneNumber();
}


// would also be good if the order summary displayed it.

p.btnAddPhoneNumber_onclick = function() {
    // need to know the new index of the phone number that is being added
    
    // validation? perhaps the click can only happen if the button is enabled,
    // if it is valid.
    
    phoneNumberIndex = getFreePhoneNumberIndex();
    // the phone number should have been saved automatically.
    this.numberEntry.clear();
    //var newPN = this.numberEntry.getPhoneNumber();
    //phoneNumbers[phoneNumberIndex] = newPN;
    //newPN.options.numLines = 1;
    //newPN.dnjkdsf.fdsfadf.fdsfafd;
    
    // When displaying the order summary, it would be best not to show the new number until anything has been typed in.
    // But now I think it is best
    
    //updateOrderSummary(newPN);
    this.numberEntry.updateOrderSummary();
    
    
    
    this.updateNumberTitle();
    // Don't need to 'add' this phone number, it should already be listed, even if it is not
    // valid. However, we don't allow the user to continue if it is not valid.
    
    // No need to do validation, as the number will go green in the listing if it is
    // valid.
    
    //var phoneNumberIsValid = this.numberEntry.isPhoneNumberValid();
    //alert ('phoneNumberIsValid ' + phoneNumberIsValid);
    
    // Also need to validate a phone number when it is entered.
    
    // the button should only be enabled if the number is valid.
    
//    if (phoneNumberIsValid) {
//        var phoneNumber = this.numberEntry.getPhoneNumber();
//        
//        // need to validate the phone number
//        //this.numberEntry.hide();
//        //this.btnAddPhoneNumber.hide();
//        //this.cdEnterAnotherNumberQuestion.show();
//        
//        addPhoneNumber(phoneNumber);
//        this.numberN = this.numberN + 1;
//        //this.cdhNumberN = new CDiv(this, {'cssClass': 'title'});
//        this.cdhNumberN.setInnerHTML('Telephone number ' + this.numberN);
//        
//        
//        this.numberEntry.clear();
//    } else {
//        alert ('The phone number you have entered is not valid.');
//    }
    // add it to the order
    //this.container.order.addPhoneNumber(phoneNumber);
    // add it to the summary of phone numbers.
    
}
p.numberEntry_complete = function(obj) {
    var tariff = obj.number.tariff;
    if (tariff) 
    {
        this.completedNumbers.add(obj.number);
    }
    else
    {
        alert ('Please select a tariff');
    }
}


// Not needed
RegisterBox.PhoneNumber = function(div, phoneNumbers) {
    this.div = div;
    this.phoneNumbers = phoneNumbers;
    this.init();
}
var p = RegisterBox.PhoneNumber.prototype;
p.init = function() {
    
}
//// Maybe no need for this - could use the CheckBoxMenu.

// No, will use a new-and-improved addOns selector after all.
// This should show some difference between the international calling plan and the calling features.
// Perhaps having different colours in the box

// Do show the price to the right of it after all.

// Is needed, in a different form. Separate style from presentation.

RegisterBox.AddOnsSelector = function(container, options) {
    this.container = container;
    this.options = options;
    //this.phoneNumbers = phoneNumbers;
    
    this.init(0);
}
var p = RegisterBox.AddOnsSelector.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('AddOnsSelector');
    this.lTitle = new CDLabel(this, {'text':'Select your add-ons'});
    this.lTitle.setClass('title');
    //this.lTitle.setInnerHTML('Select your add-ons');
    
    var standardAddOnItems = new Array();
    var featureAddOnItems = new Array();
    for (var c = 0; c < addOns.length; c++) {
        var aoo = new Object();
        aoo.text = addOns[c].options.name + ':';
        aoo.value = addOns[c].options.value;
        aoo.object = addOns[c];
        
        var aoAddOn = new AOption(aoo);
        if (addOns[c].options.category == 'standard') {
            standardAddOnItems.push(aoAddOn);
        }
        if (addOns[c].options.category == 'feature') featureAddOnItems.push(aoAddOn);
    }
    
    // The CDiv inside could have a class so we can set the label width with CSS.
    //  That should not be in the code.
    this.standardAddOnMenu = new CheckBoxMenu(this, {'items':standardAddOnItems, 'renderMode': 'CheckBoxInMiddle', 'labelWidth': 251} );
    this.standardAddOnMenu.setClass('standardAddOnMenu');
    this.standardAddOnMenu.render();
    // this.addOnMenu should react to changes
    this.standardAddOnMenu.onchange = function() { this.container.standardAddOnMenu_onchange(); return false; }
    
    //
    //this.cbIncludeLineFeatures = new CheckBox(this, {'text': 'Would you like any line features?', 'checkboxPosition': 'right'});
    //this.cbIncludeLineFeatures.onchange = function() { this.container.cbIncludeLineFeatures_onchange(); }
    
    // should be able to set the width of the left section of this...
    // though that should really be in CSS.
    
    this.cbIncludeLineFeatures = new YesNoRadioField(this, {'labelText': 'Add line features/services?', 'cssClass':'QuestionLineFeatures'});
    //this.cbIncludeLineFeatures.onchange = function() { this.container.cbIncludeLineFeatures_onchange(); }
    
    // maybe need another event apart from onclick / onchange.
    // onclick gets called from the CDiv, do we need it to get called from another control too?
    // we don't want the onclick from the CDiv, the standard one.
    // Events will have to be re-done before too long.
    
    this.cbIncludeLineFeatures.onclick = function() { return this.container.cbIncludeLineFeatures_onclick(); }
    
    //YesNoRadioField
    
    //this.lblFeatures = new CDLabel(this, {'text': 'Each line feature is only £1.49 per month', 'cssClass':'cdlLineFeatures'});
    //this.lblFeatures.hide();
    
    //this.featureAddOnMenu = new CheckBoxMenu(this, {'items':featureAddOnItems, 'renderMode': 'CheckBoxOnRight', 'labelWidth': 252});
    this.featureAddOnMenu = new CheckBoxMenu(this, {'items':featureAddOnItems, 'renderMode': 'CheckBoxInMiddle', 'labelWidth': 251});
    
    //CheckBoxInMiddle
    
    //this.featureAddOnMenu = new CheckBoxMenu(this, {'items':featureAddOnItems, 'renderMode': 'CheckBoxOnRight', 'labelWidth': 194, 'cssClass':'cbmLineFeatures'});
    //this.featureAddOnMenu = new CheckBoxMenu(this, {'items':featureAddOnItems, 'renderMode': 'CheckBoxInMiddle', 'labelWidth': 194, 'cssClass':'cbmLineFeatures'});
    this.featureAddOnMenu.hide();
    this.featureAddOnMenu.render();
    // this.addOnMenu should react to changes
    this.featureAddOnMenu.onchange = function() { return this.container.featureAddOnMenu_onchange(); }
    this.addMyDiv();
}

// This probably should not be called more than once per click... but it happens.
//var cbIncludeLineFeatures_onchangeCount = 0;
p.cbIncludeLineFeatures_onclick = function() {
    // this seems to get called a few times when it gets clicked on.
    // it should not, getting called once when an item is clicked on should be enough.
    
    //alert('cbIncludeLineFeatures_onchange');
    //if (cbIncludeLineFeatures_onchangeCount == 2) {
    //    cbIncludeLineFeatures_onchangeCount.esdfadsf.dasfdsa.dsaf();
    //}
    
    //this.
    //var val = this.cbIncludeLineFeatures.getValue();
    var val = this.cbIncludeLineFeatures.getValue();
    //alert ('val ' + val);
    
    if (val) {
        //this.lblFeatures.show();
        this.featureAddOnMenu.show();
    } else {
        //this.lblFeatures.hide();
        this.featureAddOnMenu.hide();
    }
    if (this.onchange) this.onchange();
    
    //cbIncludeLineFeatures_onchangeCount++;
}

// This should be flexable in rendering, maybe like a repeater control.
p.clear = function() {
    this.standardAddOnMenu.clear();
    this.featureAddOnMenu.clear();
}

p.getSelectedValues = function() {
    var standardAddOnItems = this.standardAddOnMenu.getSelectedValues();
    var featureAddOnItems = this.featureAddOnMenu.getSelectedValues();
    var res = new Array();
    for (var c = 0; c < standardAddOnItems.length; c++) {
        res.push(standardAddOnItems[c].options.object);
    }
    
    if (this.cbIncludeLineFeatures.getValue()) {
        for (var c = 0; c < featureAddOnItems.length; c++) {
            res.push(featureAddOnItems[c].options.object);
        }
    }
    
    
    return res;
}

p.setSelectedValues = function(/*add-ons*/ value) {
    // We get given an array of values.
    
    
    
    // will need to update the sub-controls with the addons
    
    // go through standardAddOnItems
    // featureAddOnItems
    
    // mapping from the add-ons to the items in the table?
    
    // The checkBoxMenu takes a list of items.
    // Do we do this in an efficient way?
    
    // need to go through this.
    // the items each have an id.
    
    //alert ('setSelectedValues value.length ' + value.length);
    var isSelected = {};
    for (var c = 0; c < value.length; c++) {
        isSelected[value[c].options.id] = true;
        //alert('value[c].options.id ' + value[c].options.id);
    }
    
    // go through both the arrays looking for the items we have here.
    
    //alert('this.featureAddOnMenu.options.items.length ' + this.featureAddOnMenu.options.items.length);
    
    for (var c = 0; c < this.standardAddOnMenu.options.items.length; c++) {
        var i = this.standardAddOnMenu.options.items[c];
        
        var id = i.options.object.options.id
        //alert('id ' + id + ', isSelected[id] ' + isSelected[id]);
        //alert('i.options.object.options.id ' + i.options.object.options.id);
        //if (
        
        //alert ('isSelected[id] ' + isSelected[id]);
        
        if (isSelected[id]) {
            i.setSelected(true);
        } else {
            i.setSelected(false);
        }
        
        
    }
    this.standardAddOnMenu.render();
    
    
    for (var c = 0; c < this.featureAddOnMenu.options.items.length; c++) {
        var i = this.featureAddOnMenu.options.items[c];
        //alert('i.aoo.options.id ' + i.options.object.options.id);
        //alert('i.options.object.options.id ' + i.options.object.options.id);
        //if (
        var id = i.options.object.options.id
        //alert('id ' + id + ', isSelected[id] ' + isSelected[id]);
        //alert('i.options.object.options.id ' + i.options.object.options.id);
        //if (
        
        if (isSelected[id]) {
            i.setSelected(true);
        } else {
            i.setSelected(false);
        }
    }
    this.featureAddOnMenu.render();
    
    //this.render();
    
    //this.standardAddOnMenu.options.items
    
    
    
    
    
}

p.standardAddOnMenu_onchange = function() {
    if (this.onchange) this.onchange();
}
p.featureAddOnMenu_onchange = function() {
    if (this.onchange) this.onchange();
}

p.tcb_change = function(tcb) {
    this.selectionStatae[tcb.addOn.id] = tcb.value;
}

// Maybe just a TextField with a Regex.

UKLandlineNumberInput = function(container) {
    this.container = container;
    this.init(0);
}
var p = UKLandlineNumberInput.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.ddlAreaCode = new CDDropDownList(this);
    this.ddlAreaCode.add(new AOption({'text':'01', 'value':'01'}));
    this.ddlAreaCode.add(new AOption({'text':'02', 'value':'02'}));
    this.ddlAreaCode.add(new AOption({'text':'03', 'value':'03'}));
    this.ddlAreaCode.setStyle('marginLeft', '10px');
    
    this.ddlAreaCode.render();
    this.ddlAreaCode.setFloat('left');
    
    this.textBox = new CDTextBox(this);
    this.textBox.setStyle('marginLeft', '10px');
    this.textBox.setFloat('left');
    
    this.addMyEl();
}
p.clear = function() {
    this.ddlAreaCode.clear();
    this.textBox.clear();
    
}
p.getValue = function() {
    return this.ddlAreaCode.getValue() + this.textBox.getValue();
}
p.validate = function() {
    
}

// The landline number field would be good if has validation, and displays the validation problem(s) next to it.
// If the user tries typing in any letters (or anything that is not a number) it cancels that keystroke and

// uk landline field automatically puts a space in when the user is typing, once they have finished the area code.

// Maybe shows an achtung with text saying 'The Landline Number field can only contain numbers'.
// For the moment just cancel any non-number key they press.

// Let's have an achtung appear if they leave the focus of the textbox while the number is not correct.
// Maybe just a TextField with a Regex.

UKLandlineNumberField = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = UKLandlineNumberField.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(0);
    this.uid = UID();
    this.setClass('UKLandlineNumberField');
    if (!this.options) this.options = new Object();
    if (!this.options.labelText) this.options.labelText= 'Landline Number: ';
    if (!this.options.isRequired) this.options.isRequired = true;
    
    var strVF = '';
    if (this.options.isRequired) strVF = '<span class="validationFailure">*</span>';
    
    var o = {'text':this.options.labelText + strVF,'cssFloat':'left', 'labelWidth': 194};
    
    if (this.options.labelWidth) 
    if (!this.options.itemPadding) {
        // or is there a default item padding I can get?
        this.options.itemPadding = 10;
    }
    
    this.cdLabel = new CDLabel(this, o);
    
    //this.ukLandlineNumberInput = new UKLandlineNumberInput(this);
    //this.inputControl = this.ukLandlineNumberInput;
    
    this.ukLandlineNumberInput = new TextBox(this);
    
    // extra behaviour on the textbox?
    // easier event attachment would be better. Would be more efficient with more direct handling of events from elements.
    // Probably better to use the jQuery event system ASAP.
    var that = this;
    this.ukLandlineNumberInput.onblur = function() {
    
        this.container.showOrHideAchtung();
        
        //this.container.ukLandlineNumberInput_onchange()
        //alert('onblur');
        
        // check to see if the number is valid or not.
        // if it is not, show an achtung next to it saying the number is not valid.
        
        
    }
    this.ukLandlineNumberInput.onfocus = function() {
        
        //that.hideAchtung();
        //this.container.ukLandlineNumberInput_onchange()
        //alert('onblur');
        
        // check to see if the number is valid or not.
        // if it is not, show an achtung next to it saying the number is not valid.
        
        
    }
    
    this.ukLandlineNumberInput.onchange = function() {this.container.ukLandlineNumberInput_onchange()}
    this.ukLandlineNumberInput.onkeypress = function() {this.container.ukLandlineNumberInput_onkeypress()}
    this.ukLandlineNumberInput.onkeyup = function() {this.container.ukLandlineNumberInput_onkeyup()}
    
    this.inputControl = this.ukLandlineNumberInput;
    
    
    this.ca = new CDClear(this);
    
    // then another div the contain any validation information.
    
    this.cdValidation = new CDiv(this, {'cssClass': 'validation'});
    // perhaps there could be more than one 'achtung' in the validation area.
    
    this.addMyEl();
}

p.showOrHideAchtung = function() {
    if (this.isValid() || this.getValue().length === 0) {
        //that.showAchtung();
        this.hideAchtung();
    } else {
        //that.hideAchtung();
        
        this.showAchtung('Landline numbers must be in the format: 0xxxx xxxxxx, and start with 01, 02 or 03.');
    }
}

p.showAchtung = function(text) {
    //alert('showAchtung');
    // create a new achtung next to the textbox (just to the right of it). show it with jQuery.
    
    // am having trouble using the programming style I have here with jQuery :(
    
    //var tbPos = $(this.ukLandlineNumberInput.el).position();
    
    this.cdValidation.setInnerHTML('<div class="achtung">' + text + '</div>');
    //alert('tbPos.left ' + tbPos.left + ', tbPos.top ' + tbPos.top);
    // put the achtung in this.cdValidation.
    
    
    
    
}
p.hideAchtung = function() {
    this.cdValidation.setInnerHTML('');
}

p.ukLandlineNumberInput_onchange = function() {
    //alert ('ukLandlineNumberInput_onchange');
    if (this.onchange) this.onchange();
}
p.ukLandlineNumberInput_onkeypress = function() {
    //alert ('ukLandlineNumberInput_onkeypress');
    if (this.onkeypress) this.onkeypress();
}

// on key down check that it is a digit?

p.ukLandlineNumberInput_onkeyup = function() {
    //alert ('ukLandlineNumberInput_onkeypress');
    if (this.onkeyup) this.onkeyup();
}
p.clear = function() {
    this.inputControl.clear();
}
p.getValue = function() {
    return this.inputControl.getValue();
}
p.setValue = function(value) {
    var res = this.inputControl.setValue(value);
    this.showOrHideAchtung()
    return res;
}
p.validate = function() {
    // use a regular expression on the number generated by getValue;
    
    var res = new ValidationResult({'isValid':this.isValid()});
    return res;
    
}
p.isValid = function() {
    var v = this.getValue();
    var res = true;
    
    // needs to start with 01, 02, 03
    // may be worth putting somewhere that it requires this as user feedback.
    
    if (!(v.match(/^(0(1|2|3)\d{9,10}|0(1|2|3)\d{3} \d{6,7})$/))) res = false;
    return res;
}

// Almost certainly not needed.

PricePreview = function(container) {
    this.container = container;
    this.init(0);
}
var p = PricePreview.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('PricePreview');
    
    this.monthlyPrice = 9.99;
    
    this.el.innerHTML = '... Per Month';
    
    this.addMyEl();
}
p.setOrderPhoneNumber = function(value) {
    
}
p.setPrice = function(value) {
    this.price = value;
    this.setInnerHTML(this.price.toFixed(2) + ' Per Month');
    
}