﻿var ValidationError = function(field, description)
{
    this.field = field;
    this.description = description;
}

var OrderForm = Class.create({

    initialize: function(clientID)
    {
        this.clientID = clientID;

        // Fix up the submit button so we get a chance to verify on the client
        // side before sending off to the server.
        var btnSubmitOrder = this.FindControl("btnSubmitOrder");
        var submitCommand = btnSubmitOrder.href.substring(btnSubmitOrder.href.indexOf("javascript:"));

        Event.observe(btnSubmitOrder, "click", function(event)
        {
            if (this.VerifyOrder())
                eval(submitCommand);
            event.stop();
        } .bindAsEventListener(this));


        // ProductList calls this global function whenever a product is added
        // or removed. By defining it here, we can receive these updates.
        window.ProductList_PriceChanged = this.TotalPriceChanged.bind(this);
        
        // Set up the initial price.
        this.totalPrice = 0;
        this.TotalPriceChanged(0);

        // Make the product cd checkbox update the price
        var chkProductCD = this.FindControl("chkProductCD");
        Event.observe(chkProductCD, "change", function(event)
        {
            if (chkProductCD.checked)
                this.TotalPriceChanged(30);
            else
                this.TotalPriceChanged(-30);
        }.bind(this));

        // See if it was checked initially and update the price if it was.
        if (chkProductCD.checked)
            this.TotalPriceChanged(30);
    },

    FindControl: function(controlID)
    {
        var fullID = this.clientID + "_" + controlID;
        return $(fullID);
    },

    TotalPriceChanged: function(amount)
    {
        this.totalPrice += amount;
        var priceString = this.totalPrice.toFixed(2) + "";
        $("txtTotalPrice").value = priceString.addCommas();
    },

    VerifyOrder: function()
    {
        var productListID = this.clientID + "_oProductList";
        var productList = window[productListID];
        var isAnyProductSelected = false;

        var errors = [];

        isAnyProductSelected = productList.Verify();

        if (!isAnyProductSelected)
        {
            errors.push(new ValidationError("productID", "No product was selected."));
        }
        else
        {
            this.FindControl("txtSelectedProducts").value = productList.selectedProducts.join(";");
            this.FindControl("txtSelectedDiscounts").value = productList.selectedDiscounts.join(";");
        }

        var txtCustomerFirstName = this.FindControl("txtCustomerFirstName").value;
        var txtCustomerLastName = this.FindControl("txtCustomerLastName").value;
        var txtCustomerEmail = this.FindControl("txtCustomerEmail").value;
        var txtCustomerPhone = this.FindControl("txtCustomerPhone").value;
        var txtCustomerAddress1 = this.FindControl("txtCustomerAddress1").value;
        var txtCustomerAddress2 = this.FindControl("txtCustomerAddress2").value;
        var txtCustomerCity = this.FindControl("txtCustomerCity").value;
        var txtCustomerState = this.FindControl("txtCustomerState").value;
        var txtCustomerZipcode = this.FindControl("txtCustomerZipcode").value;
        var txtCardName = this.FindControl("txtCardName").value;
        var cboCardType = this.FindControl("cboCardType").value;
        var txtCardNumber = this.FindControl("txtCardNumber").value;

        if (txtCustomerFirstName == null || txtCustomerFirstName == "")
            errors.push(new ValidationError("firstName", "Please enter your first name."));

        if (txtCustomerLastName == null || txtCustomerLastName == "")
            errors.push(new ValidationError("lastName", "Please enter your last name."));

        if (txtCustomerEmail == null || txtCustomerEmail == "")
            errors.push(new ValidationError("emailAddress", "Please enter your email address."));

        if (!(txtCustomerEmail == null || txtCustomerEmail == "") && !this.VerifyEmail(txtCustomerEmail))
            errors.push(new ValidationError("emailAddress", "Your email address does not appear to be valid."));

        if (txtCustomerPhone == null || txtCustomerPhone == "")
            errors.push(new ValidationError("phoneNumber", "Please enter your phone number."));

        if ((txtCustomerAddress1 == null || txtCustomerAddress1 == "") && (txtCustomerAddress2 == null || txtCustomerAddress2 == ""))
            errors.push(new ValidationError("address1", "Please fill in at least one of the address fields."));

        if (txtCustomerCity == null || txtCustomerCity == "")
            errors.push(new ValidationError("city", "Please enter your city name."));

        if (txtCustomerState == null || txtCustomerState == "")
            errors.push(new ValidationError("state", "Please enter your state / province."));

        if (txtCustomerZipcode == null || txtCustomerZipcode == "")
            errors.push(new ValidationError("zipCode", "Please enter your zip / postal code."));

        if (txtCardName == null || txtCardName == "")
            errors.push(new ValidationError("cardName", "Please enter the name on your credit card."));

        if (cboCardType == null || cboCardType == "")
            errors.push(new ValidationError("cardType", "Please select a credit card type."));

        if (txtCardNumber == null || txtCardNumber == "")
            errors.push(new ValidationError("cardNumber", "Please enter your credit card number."));

        if (!(txtCardNumber == null || txtCardNumber == "") && this.VerifyCreditCard(cboCardType, txtCardNumber) > 0)
            errors.push(new ValidationError("cardNumber", "Your credit card number does not appear to be valid."));

        if (errors.length > 0)
        {
            this.DisplayValidationReport(errors);
            return false;
        }
        else
            return true;
    },

    VerifyEmail: function(address)
    {
        var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        return filter.test(address);
    },

    VerifyCreditCard: function(type, inNumber)
    {
        // returns 0 if valid, positive number if invalid.
        total = 1 * 0;
        tmp = 1 * 0;

        number = "";

        // make sure there are only numbers in the string...
        for (i = 0; i < inNumber.length; i++)
        {
            if (inNumber.charAt(i) >= "0" && inNumber.charAt(i) <= "9")
            {
                number = number + inNumber.charAt(i);
            }
        }

        if (number.length < 13) return 10; // too short for anything

        first = "" + number.charAt(0);
        second = "" + number.charAt(1);
        third = "" + number.charAt(2);
        firstTwo = first + second;
        firstFour = firstTwo + third + number.charAt(3);

        if (type == "Mastercard")
        {
            if (first != "5" || second < "1" || second > "5")
                return 11; // invalid Mastercard prefix
            if (number.length != 16)
                return 21;
        }
        else if (type == "Visa")
        {
            if (first != "4")
                return 12; // invalid Visa prefix
            if (number.length != 13 && number.length != 16)
                return 22;
        }
//        else if (type == "American Express")
//        {
//            if (first != "3" || (second != "4" && second != "7"))
//                return 13; // invalid American Express Prefix
//            if (number.length != 15)
//                return 23;
//        }
        else if (type == "Discover")
        {
            if (firstFour != "6011")
                return 14; // invalid prefix.
            if (number.length != 16)
                return 24;
        }
        else if (type == "Diners")
        {
            if (firstTwo != "36"
                        && firstTwo != "38"
                        && (firstTwo != "30" ||
                                (third < "0" || third > "5")))
            {
                return 15;
            }
            if (number.length != 14)
                return 25;
        }
        else if (type == "enRoute")
        {
            if (firstFour != "2014"
                        && firstFour != "2149")
                return 16; // invalid enRoute card
            if (number.length != 15)
                return 26;
            return 0; // no check sum calculation needed
        }
        else if (type == "JCB")
        {
            if (firstFour != "2131"
                        && firstFour != "1800"
                        && (first != "3"))
                return 17;
            if (number.length != 16 && first == "3")
                return 27;
            if (number.length != 15 && first != "3")
                return 28;
        }
        // now check the credit card suffix and length vs. the type

        // do the check sum
        for (loc = number.length - 2; loc >= 0; loc -= 2)
        {
            total += 1 * number.charAt(loc + 1);
            tmp = number.charAt(loc) * 2;
            if (tmp > 9) total += 1;
            total += tmp % 10;
        }
        if (number.length % 2 > 0)
            total += 1 * number.charAt(0);

        return (total % 10);
    },

    // This method forward the call to a global function provided by the page
    // to display any validation errors.
    DisplayValidationReport: function(errors)
    {
        if (window.DisplayValidationReport)
            window.DisplayValidationReport(errors);
    }
});