/**
 * JavaScript for the onOne cart page.
 * 
 * Luis A. Echeverria
 * September 2009
 * 
 */
Cart = function() {
    
    /**
     * Runs on document ready state.
     * 
     * 
     */
    $(document).ready(function() {
        $('#billing_to_shipping').bind('click', billingToShippingOnclick);
        $('input[name=delivery_type]').bind('click', deliveryTypeOnclick);
        $('#bill_state').bind('change', stateOnchange);
        $('#bill_country').bind('change', countryOnchange);
        $('#ship_state').bind('change', stateOnchange);
        $('#ship_country').bind('change', countryOnchange);
        $('#shipping_method').bind('change', function() {
            updateTotals();
            $(this).data('last_val', $(this).val());
        });
        $('input[name=payment_method]').bind('click', toggleCreditCardFields);
        $('#apply_promo_code, #update_qty').bind('click', function() {
            $('#submit_type').val($(this).attr('id'));
            $('#order-form').submit();
        });
        // CVV popup.
        $('#cvv_what').attr('href', 'javascript:void(0);')
                      .bind('click', function() {
            var cfg = 'toolbar=0,location=0,height=590,width=560,menubar=0,' +
                      'scrollbars=0,resizable=0';
            window.open('cart/cvv', '', cfg);
        });
        // Prevent duplicate form submissions.
        $('input[name=submit]').bind('click.disable_submit', function() {
            if ($.support.opacity) {
                $(this).fadeTo(500, 0.5);
            }
            $(this).unbind('click.disable_submit').click(function() {
                return false;
            });
        });
    });

    /**
     * Onclick handler for the delivery type radios.
     * 
     * 
     */
    function deliveryTypeOnclick() {
        // Don't fire this if there's only one radio.
        if ($('input[name=delivery_type]').length == 1) {
            return;
        }
        // Determine what to show/hide.
        if (this.checked && $(this).val() == 'dl') {
            // Hide shipping-related address items.
            $('.same_bill_ship, #shipping_info, ' +
              '#shipping_method_container, .order-summary .note').fadeOut();
            // Reset shipping methods.
            $('#shipping_method option:eq(0)').attr('selected', true);
            // Update order summary totals.
            updateTotals();
        } else if (this.checked && $(this).val() == 'box') {
            // Show shipping-related address items.
            $('.same_bill_ship, #shipping_method_container, ' +
              '.order-summary .note').fadeIn();
            // Populate shipping methods select.
            getShippingMethods();
            if ($('#billing_to_shipping').length &&
                $('#billing_to_shipping')[0].checked) {
                // Show shipping address items if "billing to shipping" is
                // checked.
                $('#shipping_info').fadeOut();
            } else {
                // Hide shipping address items.
                $('#shipping_info').fadeIn();
            }
        }
    }

    /**
     * Onclick handler for the "billing to shipping" checkbox.
     * 
     * 
     */
    function billingToShippingOnclick(e) {
        if ($('#billing_to_shipping').length &&
            $('#billing_to_shipping')[0].checked) {
            $('#shipping_info').fadeOut();
            getShippingMethods('ship');
        } else {
            $('#shipping_info').fadeIn();
            getShippingMethods('bill');
        }
    }

    /**
     * Onchange handler for a state select.
     * 
     * 
     */
    function stateOnchange() {
        getShippingMethods($(this).attr('class'));
    }

    /**
     * Onchange handler for a country select. Makes an Ajax request that
     * returns states (if any) for the selected country.
     * 
     * 
     */
    function countryOnchange() {
        var url             = base_url + 'cart/get_states_by_country_id_json/' +
                              encodeURIComponent($(this).val()),
            selected_option = $(this).find('option:selected'),
            orig_country    = $(selected_option).text(),
            select          = this;
        if ($(this).val().length) {
            // Show a "please wait" as the selected option's text.
            $(selected_option).text('Please wait...');
            $(select).attr('disabled', true);
        } else {
            // Country is not selected -- no need to query the server.
            configureStateInput([], select, orig_country);
            getShippingMethods($(this).attr('class'));
            return;
        }
        // Make an Ajax request.
        $.ajax({
            type: 'GET',
            dataType: 'json',
            url: url,
            success: function(results) {
                configureStateInput(results, select, orig_country);
                getShippingMethods($(select).attr('class'));
            },
            error: function() {
                alert('An error has occurred.');
            }
        });
    }

    /**
     * Configures state input. Populates with states (if any).
     * 
     * 
     */
    function configureStateInput(results, select, orig_country) {
        // Get either billing or shipping state input from the country select.
        // Store name and id for later use, since we might modify it.
        var delivery_type    = $(select).attr('id').replace(/_country$/, ''),
            state_input      = $('#' + delivery_type + '_state'),
            state_input_name = $(state_input).attr('name'),
            state_input_id   = $(state_input).attr('id'),
            state_input_type = $(state_input).get(0).type;
        // Set selected option back to original country and enable it.
        // (Clears "please wait" message.)
        $(select).attr('disabled', false)
                 .find('option:selected').text(orig_country);
        // See if there are states for this country.
        if (results.length) {
            // There are states for this country. Process.
            if (state_input_type == 'select-one') {
                // Input is currently a select. Clear options.
                state_input.find('option').remove();
            } else if (state_input_type == 'text') {
                // Input is currently a text input. Replace it with a select.
                state_input.replaceWith(
                    $(document.createElement('SELECT'))
                        .attr({
                            name: state_input_name,
                            id: state_input_id
                        }).addClass(delivery_type)
                          .bind('change', stateOnchange)
                );
            }
            // Populate the select with states.
            $(results).each(function(i) {
                $(document.createElement('OPTION'))
                    .text(this.state_nm)
                    .val(this.state_abbr)
                    // Notice that we're not using state_input here, since it
                    // might have been removed from the DOM above.
                    .appendTo($('#' + state_input_id));
            });
            $('#' + state_input_id).parent().fadeIn();
        } else if (state_input_type == 'select-one') {
            // There are no states for this country, and the state input is
            // currently a select. Make it a text input.
            $(state_input).replaceWith(
                $(document.createElement('INPUT'))
                    .attr({
                        name: state_input_name,
                        id: state_input_id
                    })
            );
            $('#' + state_input_id).parent().fadeOut();
        } else {
            $('#' + state_input_id).parent().fadeOut();
        }
    }

    /**
     * Get shipping methods from billing or shipping state or country
     * dropdowns.
     * 
     * 
     */
    function getShippingMethods(input_class) {
        // Determine which dropdowns to base shipping off of.
        if ($('#billing_to_shipping').length &&
            $('#billing_to_shipping')[0].checked) {
            var delivery_type = 'bill';
        } else {
            var delivery_type = 'ship';
        }
        // If input_class was passed, check to see that the classname matches
        // the delivery type. If not, exit here. This prevents, for instance,
        // the billing country dropdown from trying to get shipping methods
        // when the "billing to shipping" checkbox is unchecked.
        if (typeof trigger_delivery_type != 'undefined' &&
            input_class != delivery_type) {
            return;
        }
        var state_input   = $('#' + delivery_type + '_state'),
            country_input = $('#' + delivery_type + '_country')
            url           = base_url + 'cart/get_shipping_methods_json/',
            label         = (delivery_type == 'bill') ? 'billing' : 'shipping',
            qty           = parseInt($('input[name=quantity]').val());
        // Set up Ajax request.
        $.ajaxSetup({
            type: 'GET',
            dataType: 'json',
            url: url,
            success: function(results) {
                populateShippingMethods(results);
                updateTotals();
            },
            error: function() {
                alert('An error has occurred.');
            }
        });
        if (state_input.get(0).type == 'select-one') {
            // The state input is currently a select.
            if (state_input.val().length) {
                // A state is selected. Get the shipping methods using the
                // state id from the server.
                $.ajax({
                    url: url + 'state/' + encodeURIComponent(state_input.val()) +
                         '/' + encodeURIComponent(qty)
                });
            } else {
                // No state selected. Empty shipping method select and show a
                // message to the user.
                $('#shipping_method option').remove();
                $(document.createElement('OPTION'))
                    .text('Please select a ' + label + ' state...')
                    .val('')
                    .appendTo('#shipping_method');
                updateTotals();
            }
        } else if (country_input.val().length) {
            // A country is selected, and this country doesn't have any states
            // associated with it. Get the shipping methods using the country
            // id from the server.
            $.ajax({
                url: url + 'country/' + encodeURIComponent(country_input.val()) +
                     '/' + encodeURIComponent(qty)
            });
        } else {
            // Empty the shipping method and show a message to the user.
            $('#shipping_method option').remove();
            $(document.createElement('OPTION'))
                .text('Please select a ' + label + ' country...')
                .val('')
                .appendTo('#shipping_method');
            updateTotals();
        }
    }

    /**
     * Populate shipping method options.
     * 
     * 
     */
    function populateShippingMethods(results) {
        // Delete options.
        $('#shipping_method option').remove();
        // Create a "please select" option.
        $(document.createElement('OPTION'))
            .text('Please select...')
            .val('')
            .appendTo('#shipping_method');
        // Populate with results.
        $(results).each(function(i) {
            // Create a new option and append it.
            var opt = $(document.createElement('OPTION'))
                .text(this.text)
		.attr('value', this.value)
                .appendTo('#shipping_method');
            // See if last selected value matches this one. If so, select it.
            if ($('#shipping_method').data('last_val') == this.value) {
                $(opt).attr('selected', true);
            }
        });
    }

    /**
     * Updates order summary totals.
     * 
     * 
     */
    function updateTotals() {
        // Get existing totals.
        var totals = {
            'subtotal': $('#subtotal').text(),
            'discount': $('#discount').length ? $('#discount').text() : 0,
            'shipping': $('#shipping').text(),
            'total': $('#total').text()
        };
        // Chop off dollar sign from each.
        $.each(totals, function(k, v) {
            v += ''; // Cast value to string.
            totals[k] = parseFloat($.trim('' + v.replace(/^\$/, '')));
        });
        shipping = 0;
        if ($('input[name=delivery_type]:checked').val() == 'box') {
            // This is a shipped product.
            $('#shipping').parent().fadeIn(); 
            if ($('#shipping_method option:selected').val().length) {
                // Shipped product, shipping method selected.
                var shipping = $('#shipping_method option:selected').text();
                // Match shipping price from selected shipping method text.
                shipping_parts = $.trim(shipping).match(/\$([\d\.]*)$/);
                if (shipping_parts !== null && shipping_parts.length == 2) {
                    shipping = shipping_parts[1];
                } else {
                    shipping = '0.00';
                }
                $('#shipping').text('$' + shipping);
            } else {
                // Shipped product, no shipping method selected.
                $('#shipping').text('Please choose below');
            }
        } else {
            // Download, hide shipping line in order summary.
            $('#shipping').parent().fadeOut();
        }
        // Calculate new total.
        var total = totals.subtotal + parseFloat(shipping) - totals.discount;
        if (total <= 0) {
            total = 0;
        }
        // Update new total.
        $('#total').text('$' + total.toFixed(2));
    }

    /**
     * Shows or hides credit card fields based on payment method.
     * 
     * 
     */
    function toggleCreditCardFields() {
        if ($('input[name=payment_method]:checked').val() ==
            'express_checkout') {
            $('#cc_fields').fadeOut();
        } else {
            $('#cc_fields').fadeIn();
        }
    }
}();

