;(function(global, $){
    //es5 strict mode
    "use strict";

    var inputs = $('input.stripe_public_key');
    if (inputs.length === 0) return;

    inputs.each(function(i, elem){
        $(elem).closest('form').bind('submit', catchFormSubmission);
    });

    var formElem;
    var errorHolder;
    var submitBtn;
    var submitVal;

    // Todo multiple forms on one page

    // ----------------------------------------------------------------------

    function catchFormSubmission(e) {
        formElem = $(e.target);

        // Any predefined cards?
        var predef = formElem.find(':input[name=card_hash]:first');
        var cardHash = null;

        if (predef.length > 0 && predef[0].nodeName == 'SELECT') {
            cardHash = formElem.find(':input[name=card_hash]').val();
        } else if (predef.length > 0 && predef[0].nodeName == 'INPUT') {
            cardHash = formElem.find(':input[name=card_hash]:checked').val();
        }

        if (cardHash) return true;

        errorHolder = formElem.find('.stripe_error, [data-stripe=error]');

        e.preventDefault();

        // Set the publish key
        Stripe.setPublishableKey(formElem.find('.stripe_public_key').val());

        // Remove the error message
        formElem.find('.stripe_error, [data-stripe=error]').hide().empty();

        // Set
        submitBtn = formElem.find('.stripe_submit, input[type=submit]');

        if (submitBtn.length == 0) {
            alert("Submit button not found (use class 'stripe_submit' on the submit button)");
        }

        var loadingMsg = submitBtn.data('loadingmsg') ? submitBtn.data('loadingmsg') : 'Gwirio...';

        if (submitBtn[0].nodeName == 'INPUT') {
            submitVal = submitBtn.val();
            submitBtn.attr('disabled', 'disabled').addClass('disabled').attr('value', 'Gwirio...');
        } else {
            submitVal = submitBtn.html();
            submitBtn.attr('disabled', 'disabled').addClass('disabled').html('Gwirio...');
        }

        // Params
        var params = {};
        var tempVals = {};
        tempVals['number'] = formElem.find('.stripe_number, [data-stripe=number]').val();
        tempVals['exp_month'] = formElem.find('.stripe_exp_month, [data-stripe=exp_month]').val();
        tempVals['exp_year'] = formElem.find('.stripe_exp_year, [data-stripe=exp_year]').val();
        tempVals['cvc'] = formElem.find('.stripe_cvc, [data-stripe=cvc]').val();
        tempVals['name'] = formElem.find('.stripe_name, [data-stripe=name]').val();
        tempVals['address_line1'] = formElem.find('.stripe_address_line1, [data-stripe=address_line1]').val();
        tempVals['address_line2'] = formElem.find('.stripe_address_line2, [data-stripe=address_line2]').val();
        tempVals['address_city'] = formElem.find('.stripe_address_city, [data-stripe=address_city]').val();
        tempVals['address_state'] = formElem.find('.stripe_address_state, [data-stripe=address_state]').val();
        tempVals['address_zip'] = formElem.find('.stripe_address_zip, [data-stripe=address_zip]').val();
        tempVals['address_country'] = formElem.find('.stripe_address_country, [data-stripe=address_country]').val();

        for (var key in tempVals) {
            if (tempVals[key] == undefined || tempVals[key] == 'undefined') continue;
            params[key] = tempVals[key];
        }

        try {
            Stripe.card.createToken(params, stripeResponseHandler);
        } catch (e) {
            stripeResponseHandler(null, {
                error: {
                    message: e.message
                }
            });
        }

    }

    // ----------------------------------------------------------------------

    function stripeResponseHandler(status, response) {
        if (response.error) {
            errorHolder.show().html(response.error.message);

            if (submitBtn[0].nodeName == 'INPUT') {
                submitBtn.removeAttr('disabled').removeClass('disabled').attr('value', submitVal);
            } else {submitBtn.removeAttr('disabled').removeClass('disabled').html(submitVal);}
        } else {

            formElem.find('.stripe_token, .stripe_card_token').attr('value', response['id']);

            if (typeof formElem[0].submit == 'object') {HTMLFormElement.prototype.submit.call(formElem[0]);} else {formElem[0].submit();}
        }
    }

    // ----------------------------------------------------------------------

}(window, jQuery));