/**
 * @purpose   Contrôle des formulaires MODx
 *===============================================================================
 * @version   0.6
 * @date      15/03/2010
 * @updated   16/07/2010
 * @author    g.noel@ackwa.fr for B7Studio
 * @see       http://etickets.infomaniak.ch/soap
 * @require   JQuery
 * @copyright (c) 2010 - Ackwa
 *===============================================================================
 * @todo      - Contrôle pertinence contextuelle de certaines initialisations pour
 *              optimisation performances.
 *            - Non invocation du handler change() si sélection clavier ou reset !?
 *===============================================================================
 * @history   0.1 - 15/03/10 - Création à partir version Batie 2009
 *            0.2 - 07/06/10 - Intégration console Firebug & ACK
 *            0.3 - 09/06/10 - Intégration Webcam
 *            0.4 - 16/06/10 - Corrections pour JQuery 1.4
 *            0.5 - 17/06/10 - Correction IE7 ("POST" avec "," en fin de paramètre) !
 *            0.6 - 16/07/10 - Ajout gestion "VIP" !
 *===============================================================================
 * @ack       - La logique employée par l'auteur initial n'est pas homogène : mode
 *              formulaire vs mode 100% AJAX ! Dommage...
 *            - Par précaution penser au unbind() avant mise en place "handler"
 *===============================================================================
 *
 *===============================================================================
 * Initialisation "Console"
 */
ACKConsole(((typeof console != 'undefined') ? true : false));
 
/*
 * Initialisation au chargement des pages
 */ 
$(document).ready(function() {
    /*
     * Initialisations 
     */
    $ACK.info('Initialisation AJAX SOAP'); 

    /*
     * Initialisations gestion des formulaires
     */
    ACKInitForm();
 
    /*
     * Initialisation comportement "Perte mot de passe"
     */
	$("#div_motdepasse").css('display','none');
	$(".a_motdepasse").click(function() {
		$("#fCustomer").toggle();
		$("#div_motdepasse").toggle();
		return false;
	});
	
	// affiche le tableau avec les cartes 
	$("#a_showCards").click(function(){
	    $("#tableCard").toggle();
	    return false;
	});
	
	// grise et desactive les moyens de paiements
	$("#frmCmcic input[type='submit']").attr("value", ""); 
	
	$("#conditionGE").click(function(){
		if ($("#conditionGE").is(":checked")){
			$("input[type='submit']").animate({opacity:"1"});
			$("#div_modepaiement input[type='submit']").removeAttr("disabled");
		}  else {
			$("#div_modepaiement input[type='submit']").attr("disabled", "disabled");
			$("input[type='submit']").animate({opacity:"0.3"});
		}
	});
	
	$(".a_toggleCardForm").click(function() {
		$(this).next().toggle();
        $(this).toggleClass("headbox");
		return false;
	});
	
	$("#a_deconnexion").click(function() {
		document.location.href='deconnexion';
	});
	
	$("#a_customer_modif").click(function() {
		document.location.href='modification-de-compte';
	});
	
    /*
     * Pas de code promo si le montant du panier est nul
     */
    if ($('#recapap').length && (0 == ($('#recapap').html() + 0))) {
        $('#shop_code_promo').hide();
        $('#paymentMode').hide();
    }

	/*
	 * Correction du positionnement du bloc central !?
	 */
	$("#content_gauche").css({
		position:'absolute',
		top:'150px',
		left:'20px'
	});
	
	$("#cartUpdated").hide();
	
	bb_cartRecapListener();
	bb_makeCoffee();
});


/**
 * Initialisation de la gestion ds formulaires
 */
function ACKInitForm () {
    /*
     * Initialisation "Zone" des messages d'alerte
     */
    $('.alert').css('display', 'none');
    
    /*
     * Tweak temporaire : Ajout de la class "callback_f" à l'ID de même nom ?
     */
    $("#callback_f").addClass("callback_f");
    
    /*
     * Initialisation comportement au "submit" des formulaires "ajxfrm"
     */
    bb_igniteForms();

    /*
     * Masque des champs : Télphone et Date de naissance
     */
    $('.phone').mask("+99 99 999 99 99"); //Ack bug un ? avant les deux derniers chiffres
    $('.dob').mask("99-99-9999");

   /*
    * Listener Boutons
    */
    ACKListener();
}

/**
 * Initialisation Ackwa
 */
function ACKListener () {
    /*
     * Boutons "Annuler commande", "Payer", "Panier"
     *
     * @ack  Sur une même page il peut y avoir plusieurs boutons (ex. "Panier" et "Mini Panier")
     *       avec la même fonctionnalité. Il est donc nécessaire de travailler en mode "Class"
     *       et non en mode "Id".
     */
    $('.bb_ccleaner').unbind('click').click(function() {bb_emptyCart();});
    $('.bb_checkout').unbind('click').click(function() {document.location.href = 'acheter.html'; });
    $('.bb_payment' ).unbind('click').click(function() {document.location.href = 'paiement.html';});

    /*
     * Bouton Paiement actif à la validation des CGV
     */
    if ($('#iConfirmCondition').length) {
        $('#iConfirmCondition').unbind('click').click(function() {
            bb_onoff('#iConfirmCondition', '#bb_dopay');
        });
        bb_onoff('#iConfirmCondition', '#bb_dopay');
        $('#bb_dopay').unbind('click').click(function() {
            bb_dopay($('input[type=radio][name=sPaymentType]:checked').attr('value'));
        });
    }    

    /*
     * Mise à jour du "Shippingmode" en fonction du type de carte
     *
     * @ack  L'événement est de suite invoqué pour le cas du F5 avec
     *       select déjà affecté et du "reset"
     */
    $("#bb_cardcategory").unbind('change').change(function() {
    	$.post(bb_u(), {
    		iAction: 'shippingmode',
    		iMembershipCardCategoryCode: $(this).val()
    	}, function(data){
            $("#bb_shippingmode").html(data);
    	});
    });
    $("#bb_cardcategory").change();
    
    /*
     * Surcharge du Reset des formulaires
     */
    $('input[type=reset]').unbind('click').click(function() {resetAJAXForm();});
    
    /*
     * Widgets Plus/Moins et Poubelle
     */
    ACKAddListener();
    ACKDelListener();
}

/**
 * Activation / Désactivation d'un bouton en fonction du statut d'un checkbox
 */
function bb_onoff (master, slave) {
    if ($(master).attr('checked')) {
        $(slave).attr('disabled', '');
        $(slave).show();
    }
    else {
        $(slave).attr('disabled', 'disabled');
        $(slave).hide();
    }
}

function conditions () {
    var u='conditions-generales.html';
      if (document=='login'){
            u+='?return=login.html';
            document.location.href=u;
      }else{
	Shadowbox.open({
        content:    u,
        player:     "iframe",
        title:      "conditions générales de ventes",
        height:     690,
        width:      590
    });}
        
}
/**
 * Mise à jour d'un photo de carte membre
 */
function bb_snapshot (id) {
    $.post(bb_u(), {
    	iAction:'putsnapshot',
        iMembershipCardCode:id
    }, function(data) {
    });
}

/**
 * Chargement du formulaire de paiement
 */
function bb_dopay (type) {
    $.post(bb_u(), {
    	iAction:'payment_forms',
        sPFType:type
    }, function(data) {
        /*
         * Retour à l'accueile pour le paiement à 0 et sinon soumission du
         * formulaire de la banque
         */
        if (('' == bb_trim(data)) || ('000:' == data.substring(0, 4))) {
            document.location.href = 'par-date.html';
        }
        else {
            $("#shop_checkout").hide().html(data);
            $('form').submit();
        }
    });
}

/**
 * Script de routage des requêtes AJAX. La page MODx pointe directement 
 * vers eRouter via [!eRouter!]
 */
function bb_u () {
	return 'ajaxrouter';
}

/**
 * Déclaration des fonctions de gestion widgets +/-
 * 
 * @see  Pages "Tarifs" et "Panier"
 * @ack  Utiliser éventuellement "toFixed(2)" pour formattage totaux
 */
function ACKAddListener () {
	$('.shop_a_add').unbind('click').click(function() {
		var id  = $(this).attr('id').replace(/add-/, '');
	    var max = parseInt($(this).attr('max'));
	    
	    var qte = parseInt($('#qte-'+id).html()) + 0;
	        max = (max ? max : 99);

	    if (qte < max) {
            var amt = parseFloat($('#amt-'+id).html()) + 0.00;
            var sum = parseFloat($('#total').html())   + 0.00;

	        qte++;
            if ($(this).attr('rtu')) bb_updateEntry(id, qte); // @ack Cas de la mise à jour directe dans le panier
	        sum+= amt;

            var tot = (qte * amt);

            $('#qte-'+id).html(qte);
            $('#tot-'+id).html(tot);
            $('#total').html(sum.toFixed(2));
        }

	});
    $('.shop_a_sub').unbind('click').click(function(){
    	var id  = $(this).attr('id').replace(/sub-/, '');
	    var min = parseInt($(this).attr('min'));

        var qte = parseInt($('#qte-'+id).html()) + 0;
            min = (min ? min : 0);


        if (qte > min) {
            var amt = parseFloat($('#amt-'+id).html()) + 0.00;
            var sum = parseFloat($('#total').html())   + 0.00;
            
            qte--;
            if ($(this).attr('rtu')) bb_updateEntry(id, qte); // @ack Cas de la mise à jour directe dans le panier
	        sum-= amt;

            var tot = (qte * amt);

            $('#qte-'+id).html((qte ? qte : '0'));
            $('#tot-'+id).html(tot);
            $('#total').html(sum.toFixed(2));
        }

    });
}

/**
 * Déclaration de la fonctions de gestion de l'icone "Poubelle"
 * 
 * @see  Pages "Tarifs" et "Panier"
 */
function ACKDelListener () {
    $('.a_shop_delete').unbind('click').click(function(){
        bb_updateCart('remove_entry', $(this).attr('id').replace(/cec-/, ''), null, null, $(this).attr('idt'));
    });
}

/**
 * Méthode & Fonction de "triming" d'une chaine de caractères
 */
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g, '');
}
function bb_trim (str) {
	return str.replace(/^\s+|\s+$/g, '');
}

/**
 * Appel récurrent au serveur pour conserver la session (PING)
 *
 * @ack  ATTENTION au réglage du délai (par défaut 5min)
 */
function bb_makeCoffee () {
	$(this).stopTime('coffee');
	var response_delay = 5 * 60000;
	$(this).everyTime(response_delay, 'coffee', function() {
		bb_coffeeShot();
	});
}
function bb_coffeeShot () {
	$.post(bb_u(), {
		iAction:'coffee_shot'
	}, function(data) {
	});
}

/*
 * Purge du caddy et redirection
 */
function bb_emptyCart () {
    $.post(bb_u(), {
    	iAction:'delete'
    }, function(data) {
        bb_reloadPage();
    });
}

/**
 * Collecte des erreur, demande de traduction au serveur, puis
 * affichage d'une alerte soit dans une "Modale" soit dans un 
 * "layer"
 *
 * @ack  Mecanisme de traduction "Coûteux" en performance
 * @ack  Mode modal supprimé
 */
function bb_getError (data, modal) {
	var error = true;
	
	if (('' == bb_trim(data)) || ('000:' == data.substring(0, 4))) {
        error = false;
	}
	else {
    	$.post(bb_u(), {
    		iAction: 'geterror',
    		msg: data
    	}, function (data){
    		bb_redAlert(data);
    	});
	}
	
	return error;
}

/**
 * Affichage d'un message d'alerte
 */
function bb_redAlert (data) {
    $ACK.warn(data);
	$('.alert').hide().html(data).fadeIn('normal', function() {
	});
}

/**
 * Affichage d'un message d'information
 */
function bb_greenInfo (data) {
    $ACK.info(data);
	$('.alert').hide().html(data).fadeIn('fast', function() {
		$(this).stopTime('alert');
		var response_delay = 3000;
		$(this).everyTime(response_delay, 'alert', function(){
			$(this).fadeOut('fast');
		});
	});
}

/**
 * Message de confirmation de l'envoie du mot de passe puis
 * fermeture de la fenêtre après 3 sec.
 *
 * @ack   Le load() peut poser problème en fonction du type code chargé
 *        et des éventuels conflits JS
 */
function bb_passwordSent (data, pg) {
    bb_greenInfo(pg);
}

function resetAJAXForm () {
    $ACK.log('Reset');
    if ($('.alert').length)           $('.alert').hide();
    if ($('#bb_cardcategory').length) $("#bb_cardcategory").change();
}

/*
 * Fonction invoqué en "callback" lors de la création d'une nouvelle 
 * carte -> Déplacement vers le panier.
 */
function bb_displayCardSuccess (data, loc) {
    /* 
     * @ack Il est souhaité de ne pas rester sur cette page, mais d'aller directement au panier
     *
     * bb_updatePanier();
     * $('form.ajxfrm')[0].reset();
     * resetAJAXForm();
     */
     document.location.href = (loc ? loc : 'acheter.html');
}
function bb_displaySuccess (u,m,t,w,h) {
	if (m) {
		w = !w ? 350 : w;
		h = !h ? 100 : h;
		Shadowbox.open({
			content: u,
			player: "iframe",
			title: t ? t : "Merci",
			height: h,
			width: w
		});
		$(this).stopTime('success');
		var response_delay = 3000;
		$(this).oneTime(response_delay, 'success', function(){
			Shadowbox.close();
		});
	}
	else {
		$("#success").load(u,function() {
			$(this).stopTime('success');
			var response_delay = 3000;
			$(this).oneTime(response_delay, 'success', function(){
				$(this).fadeOut("fast");
			});
		});
	}
}

function bb_cartRecapListener() {
	$(".bb_cartRecapCount").click(function(){
		var id=$(this).attr('id').replace(/add-/,'');
		var iCount=$('#iCount-'+id).val();
		//alert(iCount);
		if (iCount > 0) {
			bb_refreshStatus($('#panier'));
			$.post(bb_u(), {
				iAction: 'update_entry',
				iCommandEntryCode: $(this).attr('rel'),
				iCount: iCount
			}, function(xml){
				bb_getError(xml,true);
				bb_getCartRecap();
			});
		}
	});
}

/**
 * Rafraichissement de la "Liste des tarifs"
 */
function bb_updateSeats (iDateCode, sMembershipCardCode) {
	/*
	 * Contrôle de la présence d'une date. Puis,l'on
	 * masque la liste, l'on soumet la mise à jour, et
	 * l'on réaffiche la liste
	 */
	if (iDateCode && $('#bb_tarifs').length) {
		$.post(bb_u(), {
			iAction: 'seats_update',
			iDateCode: iDateCode,
			sMembershipCardCode: sMembershipCardCode
		}, function(data){
			$('#bb_tarifs').fadeOut('fast',function() {
				$(this).html(data).fadeIn('fast');
                //ACKAddListener();
                ACKListener();
			});
		});
	}
}

/**
 * Rafraichissement du bloc et de la page "Panier"
 * lors de la modification des quantités.
 *
 * @info  En l'état de l'algorithme, le bloc suggestion n'est pas
 *        impacté. Il n'est donc pas rafraichit.
 */
function bb_updateEntry (iCommandEntryCode, iCount) {
	/*
	 * Mise à jour de la commande
	 */
	if (iCommandEntryCode && iCount) {
		$.post(bb_u(), {
			iAction: 'update_entry',
			iCommandEntryCode: iCommandEntryCode,
			iCount: iCount
		}, function(data){
			bb_getError(data, false);
			//bb_updateSuggestions();
		});
	}
}

/**
 * Rafraichissement du bloc et de la page "Panier"
 */
function bb_updatePanier () {
	/*
	 * Contrôle de la présence d'une date, avant
	 * rafraichissement du bloc via POST
	 */
	if ($('#bb_panier').length) {
		//bb_refreshStatus($('#bb_panier').fadeIn('fast'));
		$.post(bb_u(), {
			iAction: 'blocPanier'
		}, function(data){
			$('#bb_panier').fadeOut('fast', function() {
				$(this).html(data).fadeIn('fast');
                //ACKDelListener();
                ACKListener();
			});
		});
	}
	if ($('#panier').length) {
        $.post(bb_u(), {
        	iAction: 'recap'
        }, function(data) {
        	$('#panier').fadeOut('fast', function() {
        		$(this).html(data).fadeIn('fast');
                //ACKAddListener();
                //ACKDelListener();
                ACKListener();
        	});
        });
    }
}

/**
 * Rafraichissement du bloc "Dates"
 */
function bb_updateDates (iDateCode) {
	/*
	 * Contrôle de la présence d'une date, avant
	 * rafraichissement du bloc via POST
	 */
	if (iDateCode && $('#bb_dispo').length) {
		//bb_refreshStatus($('#bb_dispo').fadeIn('fast'));
		$.post(bb_u(), {
			iAction: 'blocDates',
			iDateCode: iDateCode
		}, function(data){
			$('#bb_dispo').fadeOut('fast', function() {
				$(this).html(data).fadeIn('fast');
			});
		});
	}
}

/**
 * Rafraichissement du bloc "Suggestions"
 */
function bb_updateSuggestions () {
	/*
	 * Contrôle de la présence du bloc
	 */
	if ($('#bb_sugg').length) {
		$.post(bb_u(), {
			iAction: 'blocSuggestions'
		}, function(data){
			$('#bb_sugg').fadeOut('fast', function() {
				$(this).html(data).fadeIn('fast');
			});
		});
	}
}

/**
 * Dans les fenêtres modales le formulaire et chaque champ de celui-ci 
 * doivent avoir pour classe "ajxfrm". 
 *
 * Au "Submit", les données du formulaire sont lues, mise en forme puis 
 * transférées au serveur.
 */
function bb_igniteForms () {
    /*
     * Traitement du submit pour les formulaire "ajxfrm"
     */
    $('form.ajxfrm').submit(function() {
		/*
		 * Initialisations
		 */
		var action = $(this).attr('action');
		    action = (action ? action : bb_u());
		var fid    = $(this).attr('id');
		var els    = {};
		
		/*
		 * Lecture des données "marquées" du formulaire avec traitement
		 * spécifique pour les "checkbox". Celles-ci  seront envoyée au
		 * serveur et s'il existe "callback_pg" à la fonction "callback"
		 */
		$(this).find('.ajxfrm').each(function() {
			var theName  = $(this).attr('name');
			els[theName] = (('checkbox' == $(this).attr('type')) ? ($(this).attr('checked') ? 1 : 0) : $(this).val());
		});
		
		/*
		 * Alertes en mode "Modale" ou "Layer" ?
		 */
		var bModal = $("#bModalAlert").val();
		    bModal = (('1' == bModal) ? true : false);
		
        /*
         * Extraction de la fonction de "Callback", via la
         * recherche de la classe "callback_f" dans le formulaire
         * courant (cf. this).
         */
		var f = $(this).find('.callback_f').val();

        /*
         * Invocation de l'action déclarée, en mode POST, avec capture
         * des erreurs et "callback"
         */
		$.post(action, els, function(data) {
            $ACK.log('Action : '+action+' Callback : '+f+' Data : '+data+' Modal : '+bModal);		
			data = bb_trim(data);

			/*
			 * En l'absence d'erreur, invocation du "callback"
			 *
			 * @ack  Au regard de cet algorithme, le paramètre "data" sera toujours vide !?
			 */
			if (!bb_getError(data, bModal)) {
				if (f) (typeof els['callback_pg'] != 'undefined' ? window[f](data, els['callback_pg']) : window[f](data));
			}
		});
		
		return false;
	});
}

/**
 * Chargement d'un bloc HTML en lien et place du formulaire
 */
function ACKLoadHTML (data, id) {
    /*
     * Contrôle de la validité du layer
     */
    if ($('#'+id).length) {
        /*
         * Masquage du message d'erreur
         */
        if ($('.alert').length) $('.alert').hide();
        
        /*
         * Affectation du nouveau code HTML
         */
        $('#'+id).html(data.substring(4));
        
        /*
         * Le code HTML peut contenir un formulaire. Il faut donc
         * réactualiser les "listener" ad'hoc
         */
        ACKInitForm();
        
        /*
         * Le code HTML peut contenir un lien en mode Shadow
         * il faut donc réinitialiser la "Shadowbox"
         */
        Shadowbox.clearCache(); 
        Shadowbox.setup();
    }
}

function bb_checkModal() {
	if (!parent.Shadowbox) document.location.href = 'mon_compte.html';
}
function bb_closeModal() {
	parent.Shadowbox.close();
}
function bb_closeModalAndReloadPage(data) {
	parent.location.reload();
	parent.Shadowbox.close();
}
function bb_closeModalAndGoToPage(data,pg) {
	parent.location.href=pg;
	parent.Shadowbox.close();
}
function bb_reloadPage(data) {
	document.location.reload();
}

/**
 * Redirection vers une page
 */
function bb_gotoPage(data, page) {
	document.location.href = page;
}

function bb_msg(data) {
	bb_getError(data);
}
function bb_refreshStatus (el) {
	el.html('<div align="center"><img src="/assets/images/billeterie/ajax-loader.gif" /></div>');
}
function bb_addExistingMembershipCardDone (data) {
	bb_displayCardSuccess();
}

/**
 * Mise à jour de la commande de place(s) et rafraichissement
 * de la page et des blocs "Mini Panier" et "Dates".
 *
 * @ack  Cette nouvelle version accepte la possibilité de traiter
 *       une liste de "Tarifs / Zone / Quantités".
 */
function bb_updateCart (iAction, iCommandEntryCode, iCount, iCategoryCode, iDateCode, iTariffZoneCode, sLoc){
	var qt = 0;
	var go = 1;
 
 	/*
	 * En l'absence de quantité l'on recherche celles-ci
	 */
	if ('add_entry' == iAction) {
    	if (!iCount) {
            go     = 0;
            iCount = '';
            $.each(iCategoryCode.split(','), function(k, id){
               qt     = parseInt($('#qte-'+id).html()) + 0;
               go    += qt;
               iCount+= (iCount ? ',' : '') + qt;
             });
    	}
    }
	
	/*
	 * L'on soumet la requête au serveur avec une "Date", une "Zone" et
	 * une liste de "Quantité / Type de billet". En retour, la page est
	 * rafraichit ainsi que les blocs "Mini Panier" et "Dates"
	 */
	if (go) {
    	$.post(bb_u(), {
    			iAction: iAction,
    			iCommandEntryCode: iCommandEntryCode,
    			iCategoryCode: iCategoryCode,
    			iCount: iCount,
    			iDateCode: iDateCode,
    			iTariffZoneCode: iTariffZoneCode
    		},function(xml){
    			if (!bb_getError(xml, false)) {
                    /*
                     * Redirection ou rafraichissement ?
                     */
                    if (sLoc) {
        				bb_gotoPage(null, sLoc);
                    }
                    else {
        				if (iDateCode) {
            				bb_reloadPage(); // @ack  Trop de blocs, il est préférable de tout rafraichir
                        }
                        else {
            				bb_updatePanier();
            				bb_updateSuggestions();
            			}
        			}
    			}
    		}
    	);
    }
}

function bb_updateCartRecap (iAction, iCommandEntryCode, iCount, iCategoryCode, iDateCode, iTariffZoneCode){
	bb_refreshStatus($('#panier'));
	//alert('iAction: '+iAction+' \n iDateCode: '+iDateCode+' \niCategoryCode: '+ iCategoryCode+' \niTariffZoneCode '+iTariffZoneCode+' \niCount '+iCount+'\nu: '+u);
	$.post(bb_u(), {
			iAction: iAction,
			iCommandEntryCode: iCommandEntryCode,
			iCategoryCode: iCategoryCode,
			iCount: iCount,
			iDateCode: iDateCode,
			iTariffZoneCode: iTariffZoneCode
		},function(xml){
			bb_getError(xml,true);
			bb_getCartRecap();
		}
	);
}
function bb_createCustomer(s,iAction){
	$.post(bb_u(), {
			iAction: iAction,
			s:s
		},function(xml){
			if(!bb_getError(xml,true)) bb_gotoPage(xml, 'inscription-valide');
		}
	);
}
function bb_getCustomer(data) {
	if(!bb_getError(data)) document.location.href='modification-de-compte';
}

function bb_getCartRecap(){
	$.ajax({
		type: "POST",
		url: bb_u(),
		data: {
			iAction: 'recap'
		},
		error: function(xhr, ajaxOptions, thrownError){
			alert(xhr.status);
		},
		success: function(xml){
			//alert(xml);
			$('#panier').fadeOut("fast",
							function() {
								$(this).html(xml).fadeIn("fast");
								bb_cartRecapListener();
								//bb_getCart();
							}
						);
		}
	});
}

/*
 * Appel en "modal" de la modification d'une carte
 */
function bb_membershipCardModif (iMembershipCardCode) {
	var u='modif-carte.html?iMembershipCardCode='+iMembershipCardCode;
	Shadowbox.open({
        content:    u,
        player:     "iframe",
        title:      "Modifier les informations de la carte",
        height:     350,
        width:      640
    });
}
function bb_membershipCardModified () {
	//parent.bb_getCartRecap();
	parent.Shadowbox.close();
    parent.bb_reloadPage();
}

function bb_getCards(){
	$.ajax({
		type: "POST",
		url: bb_u(),
		data: {
			iAction: 'membership_cards'
		},
		error: function(xhr, ajaxOptions, thrownError){
			alert(xhr.status);
		},
		success: function(xml){
			$('#bb_cards').html(xml);
		}
	});
}
function bb_showMemberForm(element) {
	$(element).hide();
	form=$(element).parents('form');
	$(form).find('DIV').show();
}

function bb_showMembershipCardDates(iMembershipCardCode) {
	//$('#membership_dates').find('DIV').show();
	$.ajax({
		type: "POST",
		url: bb_u(),
		data: {
			iAction: 'membership_dates',
			iMembershipCardCode: iMembershipCardCode
		},
		error: function(xhr, ajaxOptions, thrownError){
			alert(xhr.status);
		},
		success: function(data) {
			if(data) bb_getError(data,true);
			else $('#bb_cards').html(xml);
		}
	});
}
// @obsolete ?
function bb_addMembershipCard (iCategoryCode, iShippingModeCode, sFirstname, sLastname) {
	$.ajax({
		type: "POST",
		url: bb_u(),
		data: {
			iAction: 'add_membership_card',
			iCategoryCode: iCategoryCode,
			iShippingModeCode: iShippingModeCode,
			sFirstname: sFirstname,
			sLastname: sLastname
		},
		error: function(xhr, ajaxOptions, thrownError) {
			alert('error: '+xhr.status);
		},
		success: function(data) {
			if(!bb_getError(data,true)) bb_getCartRecap();//bb_reloadPage();
		}
	});
}

/**
 * Demande de calcul de la réduction vis à vis d'un code promo
 */
function bb_dopromo (sCodepromo) {
	/*
     * Initialisation du code promo et masquage des lignes de totaux
     */
    sCodepromo = (sCodepromo ? sCodepromo : $('#sCodepromo').val());
	$('#shop_panier').hide();
	$('#shop_total').hide();
	
    $.ajax({
		type: "POST",
		url: bb_u(),
		data: {
			iAction: 'promo',
			sCodepromo: sCodepromo.trim()
		},
		error: function(xhr, ajaxOptions, thrownError){
			alert(xhr.status);
		},
		success: function(data) {
			if (!bb_getError(data,false)) {
    			/*
                 * Extraire le montant de data (suppression prefixe 000:)
                 * et affectation à la celleul ad'hoc                 
                 */                 
    			var recapap = data.substring(4);
    			$('#recapap').html(recapap);
    
    			/*
                 * Calcul réduction
                 */                 
    		    var	reduc = parseFloat(recapap) - parseFloat($('#recapav').html());
    			
                /*
                 * Affectation de la réduction dans id ad'hoc et affichage
                 */
    			$('#recapromo').html(reduc.toFixed(2));
    			bb_updatePanier();
    			$('#shop_panier').show();
    			$('#shop_total').show();
			}
		}
	});
}
function bb_addExistingMembershipCard(sMembershipCardCode) {
	sMembershipCardCode = (sMembershipCardCode ? sMembershipCardCode : $('#sMembershipCardCode').val());
	$.ajax({
		type: "POST",
		url: bb_u(),
		data: {
			iAction: 'add_membership_card',
			sMembershipCardCode: sMembershipCardCode.trim()
		},
		error: function(xhr, ajaxOptions, thrownError){
			alert(xhr.status);
		},
		success: function(data) {
			if(!bb_getError(data,false)) bb_reloadPage();
		}
	});
}

/**
 * Ajout d'un billet acheté avec une carte abonné
 */
function bb_addMembershipCardEntry (iMembershipCardCode, iDateCode, iCategoryCode, iTariffZoneCode, iCount, sLoc) {
	if (iCount > 0) {
		$.ajax({
			type: "POST",
			url: bb_u(),
			data: {
				iAction: 'add_entry',
				iMembershipCardCode: iMembershipCardCode,
				iDateCode: iDateCode,
				iCategoryCode: iCategoryCode,
				iTariffZoneCode: iTariffZoneCode,
				iCount: iCount
			},
			error: function(xhr, ajaxOptions, thrownError){
				alert(xhr.status);
			},
			success: function(data) {
				if (!bb_getError(data, false)) {
					if (sLoc) {
        				bb_gotoPage(null, sLoc);
					}
					else {
    					bb_reloadPage();
        			}
				}
			}
		});
	}
}

/**
 * Gestion des Timers
 *
 * @see   ???
 * @todo  Externaliser ?
 */
jQuery.fn.extend({everyTime:function(interval,label,fn,times,belay){return this.each(function(){jQuery.timer.add(this,interval,label,fn,times,belay)})},oneTime:function(interval,label,fn){return this.each(function(){jQuery.timer.add(this,interval,label,fn,1)})},stopTime:function(label,fn){return this.each(function(){jQuery.timer.remove(this,label,fn)})}});jQuery.extend({timer:{guid:1,global:{},regex:/^([0-9]+)\s*(.*s)?$/,powers:{'ms':1,'cs':10,'ds':100,'s':1000,'das':10000,'hs':100000,'ks':1000000},timeParse:function(value){if(value==undefined||value==null)return null;var result=this.regex.exec(jQuery.trim(value.toString()));if(result[2]){var num=parseInt(result[1],10);var mult=this.powers[result[2]]||1;return num*mult}else{return value}},add:function(element,interval,label,fn,times,belay){var counter=0;if(jQuery.isFunction(label)){if(!times)times=fn;fn=label;label=interval}interval=jQuery.timer.timeParse(interval);if(typeof interval!='number'||isNaN(interval)||interval<=0)return;if(times&&times.constructor!=Number){belay=!!times;times=0}times=times||0;belay=belay||false;if(!element.$timers)element.$timers={};if(!element.$timers[label])element.$timers[label]={};fn.$timerID=fn.$timerID||this.guid++;var handler=function(){if(belay&&this.inProgress)return;this.inProgress=true;if((++counter>times&&times!==0)||fn.call(element,counter)===false)jQuery.timer.remove(element,label,fn);this.inProgress=false};handler.$timerID=fn.$timerID;if(!element.$timers[label][fn.$timerID])element.$timers[label][fn.$timerID]=window.setInterval(handler,interval);if(!this.global[label])this.global[label]=[];this.global[label].push(element)},remove:function(element,label,fn){var timers=element.$timers,ret;if(timers){if(!label){for(label in timers)this.remove(element,label,fn)}else if(timers[label]){if(fn){if(fn.$timerID){window.clearInterval(timers[label][fn.$timerID]);delete timers[label][fn.$timerID]}}else{for(var fn in timers[label]){window.clearInterval(timers[label][fn]);delete timers[label][fn]}}for(ret in timers[label])break;if(!ret){ret=null;delete timers[label]}}for(ret in timers)break;if(!ret)element.$timers=null}}}});if(jQuery.browser.msie){jQuery(window).one("unload",function(){var global=jQuery.timer.global;for(var label in global){var els=global[label],i=els.length;while(--i)jQuery.timer.remove(els[i],label)}})}

/**
 * Gestion des masques de saisie
 *
 * @see   ???
 * @todo  Externaliser ?
 */
(function(a){var c=(a.browser.msie?"paste":"input")+".mask";var b=(window.orientation!=undefined);a.mask={definitions:{"9":"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"}};a.fn.extend({caret:function(e,f){if(this.length==0){return}if(typeof e=="number"){f=(typeof f=="number")?f:e;return this.each(function(){if(this.setSelectionRange){this.focus();this.setSelectionRange(e,f)}else{if(this.createTextRange){var g=this.createTextRange();g.collapse(true);g.moveEnd("character",f);g.moveStart("character",e);g.select()}}})}else{if(this[0].setSelectionRange){e=this[0].selectionStart;f=this[0].selectionEnd}else{if(document.selection&&document.selection.createRange){var d=document.selection.createRange();e=0-d.duplicate().moveStart("character",-100000);f=e+d.text.length}}return{begin:e,end:f}}},unmask:function(){return this.trigger("unmask")},mask:function(j,d){if(!j&&this.length>0){var f=a(this[0]);var g=f.data("tests");return a.map(f.data("buffer"),function(l,m){return g[m]?l:null}).join("")}d=a.extend({placeholder:"_",completed:null},d);var k=a.mask.definitions;var g=[];var e=j.length;var i=null;var h=j.length;a.each(j.split(""),function(m,l){if(l=="?"){h--;e=m}else{if(k[l]){g.push(new RegExp(k[l]));if(i==null){i=g.length-1}}else{g.push(null)}}});return this.each(function(){var r=a(this);var m=a.map(j.split(""),function(x,y){if(x!="?"){return k[x]?d.placeholder:x}});var n=false;var q=r.val();r.data("buffer",m).data("tests",g);function v(x){while(++x<=h&&!g[x]){}return x}function t(x){while(!g[x]&&--x>=0){}for(var y=x;y<h;y++){if(g[y]){m[y]=d.placeholder;var z=v(y);if(z<h&&g[y].test(m[z])){m[y]=m[z]}else{break}}}s();r.caret(Math.max(i,x))}function u(y){for(var A=y,z=d.placeholder;A<h;A++){if(g[A]){var B=v(A);var x=m[A];m[A]=z;if(B<h&&g[B].test(x)){z=x}else{break}}}}function l(y){var x=a(this).caret();var z=y.keyCode;n=(z<16||(z>16&&z<32)||(z>32&&z<41));if((x.begin-x.end)!=0&&(!n||z==8||z==46)){w(x.begin,x.end)}if(z==8||z==46||(b&&z==127)){t(x.begin+(z==46?0:-1));return false}else{if(z==27){r.val(q);r.caret(0,p());return false}}}function o(B){if(n){n=false;return(B.keyCode==8)?false:null}B=B||window.event;var C=B.charCode||B.keyCode||B.which;var z=a(this).caret();if(B.ctrlKey||B.altKey||B.metaKey){return true}else{if((C>=32&&C<=125)||C>186){var x=v(z.begin-1);if(x<h){var A=String.fromCharCode(C);if(g[x].test(A)){u(x);m[x]=A;s();var y=v(x);a(this).caret(y);if(d.completed&&y==h){d.completed.call(r)}}}}}return false}function w(x,y){for(var z=x;z<y&&z<h;z++){if(g[z]){m[z]=d.placeholder}}}function s(){return r.val(m.join("")).val()}function p(y){var z=r.val();var C=-1;for(var B=0,x=0;B<h;B++){if(g[B]){m[B]=d.placeholder;while(x++<z.length){var A=z.charAt(x-1);if(g[B].test(A)){m[B]=A;C=B;break}}if(x>z.length){break}}else{if(m[B]==z[x]&&B!=e){x++;C=B}}}if(!y&&C+1<e){r.val("");w(0,h)}else{if(y||C+1>=e){s();if(!y){r.val(r.val().substring(0,C+1))}}}return(e?B:i)}if(!r.attr("readonly")){r.one("unmask",function(){r.unbind(".mask").removeData("buffer").removeData("tests")}).bind("focus.mask",function(){q=r.val();var x=p();s();setTimeout(function(){if(x==j.length){r.caret(0,x)}else{r.caret(x)}},0)}).bind("blur.mask",function(){p();if(r.val()!=q){r.change()}}).bind("keydown.mask",l).bind("keypress.mask",o).bind(c,function(){setTimeout(function(){r.caret(p(true))},0)})}p()})}})})(jQuery);

/*
 * Firebug console Wrapper
 *
 * @see   http://fragged.org/creating-a-wrapper-for-the-firebug-consolelog-function-for-ie-and-other-browsers_218.html
 * @see   http://getfirebug.com/logging
 * @see   http://duvet-dayz.com/firebug-cheatsheet
 * @todo  Externaliser ?
 */
var $ACK;
function ACKConsole(start) {$ACK={_version:2.3,debug:true,quietDismiss:false,method:"log",_hasConsole:function(_method){var _method=_method||"log";return typeof(console)=='object'&&typeof(console[_method])!="undefined"},_consoleMethod:function(){if(!this.debug)return false;if(this._hasConsole(this.method)){try{console[this.method].apply(this,arguments)}catch(e){for(var i=0,l=arguments.length;i<l;i++)console[this.method](arguments[i])}}else if(!this.quietDismiss&&arguments.length){var result="";for(var i=0,l=arguments.length;i<l;i++)result+=arguments[i]+" ("+typeof arguments[i]+") ";alert(result)}},log:function(){this.method="log";this._consoleMethod.apply(this,arguments)},info:function(){this.method="info";this._consoleMethod.apply(this,arguments)},warn:function(){this.method="warn";this._consoleMethod.apply(this,arguments)},clear:function(){this.method="clear";this._consoleMethod.apply(this)},count:function(){this.method="count";this._consoleMethod.apply(this,arguments)},debug:function(){this.method="debug";this._consoleMethod.apply(this,arguments)},trace:function(){this.method="trace";this._consoleMethod.apply(this,arguments)},assert:function(){this.method="assert";this._consoleMethod.apply(this,arguments)}};$ACK.debug = start;}

