// Teste que jQuery soit bien défini
if (typeof jQuery === 'undefined') {
    alert('La librairie jQuery est nécessaire au bon fonctionnement de #JAVASCRIPT_SYSTEME# et doit être incluse avant cette balise');
}

// Déclaration de la classe Wsa
function Wsa() {
    this.init();
}

// Méthodes et propriétés de la classe Wsa
Wsa.prototype = {
    version:                "1.0",
    langue:                 "fr",
    produit:                null,
    webserviceCodepostal:   null,
    
    init: function () {
        if ((typeof (langue) !== "undefined") && langue !== '') {
            this.langue = langue;
        }
    },
    
    recupererVersion: function () {
        return (this.version);
    },
    
    chargerSelecteurDeclinaisonProduit: function () {
        // On efface le contenu du prix réduit si il n'est pas inférieur au prix normal
        if (jQuery("#ui-bouton-ajouter-produit-panier-js").find("span.ui-prix-standard").html()
                === jQuery("#ui-bouton-ajouter-produit-panier-js").find("span.ui-prix-reduit").html()) {
            jQuery("#ui-bouton-ajouter-produit-panier-js").find("span.ui-prix-reduit span").html('');
        }
        // Si le champ correspondant aux informations des sélecteurs multiples est définie,
        // alors on définie le traitement au changement d'un des sélecteurs
        if (typeof jQuery("#informationsProduitJS").val() !== 'undefined') {
            var objetCourant        = this,
                informationsProduit = jQuery("#informationsProduitJS").val(),
                parametresProduit   = jQuery.parseJSON(informationsProduit); // paramètres du produit parsé sous forme d'objet JSON    
            objetCourant.definirProduit(parametresProduit);
            // Lorsqu'un choix de sélecteur est fait :
            objetCourant.produit.elementDomSelectMulti.change(function () {
                var numeroPosition  = jQuery(this).attr("id").indexOf("_") + 1,
                    numeroSelect    = jQuery(this).attr("id").substring(numeroPosition, jQuery(this).attr("id").length);
                // On enregistre la valeur choisie
                objetCourant.produit.elementSelectionnes[numeroSelect] = jQuery(this).val();
                // et l'on met à jour les autres sélecteurs
                objetCourant.produit.mettreAJourSelectMulti(jQuery(this).attr("id"));
                // ainsi que le prix (si la sélection est complète)
                objetCourant.produit.mettreAJourPrix();
            });
        }
    },
    
    // Méthode de définition d'un produit
    definirProduit: function (donnees) {
        this.produit = new Wsa_Produit(donnees);
    },
    
    chargerWebServiceCodePostal: function (formulaire) {
        this.webserviceCodepostal = new Wsa_WebService_CodePostal(formulaire, this.langue);
    }
};
// Déclaration de la classe Wsa_Produit
function Wsa_Produit(donnees) {
    this.init(donnees);
}
  
// Méthodes et propriétés de la classe Wsa_Produit
Wsa_Produit.prototype = {         
    _idElementDom:          "#ui-bouton-ajouter-produit-panier-js",    
    _elementDom:            null,   
    elementDomBouton:       null,
    estDecline:             true,    
    estVendu:               false,
    codeProduit:            '',
    prixStandard:           0.00,    
    prixReduit:             0.00,
    stock:                  0,
    devise:                 "€",
    elementDomPrix:         null,
    donneesDeclinaisons:    null,
    declinaisons:           Array(),
    elementDomDeclinaisons: null,    
    elementDomSelectMulti:  null,
    elementSelectionnes:    Array(),
    
    // Initialisation d'une classe Wsa_Produit avec ses données (déclinaisons, prix, ...)
    init: function(donnees) {
        this.donneesDeclinaisons = donnees;
        this._elementDom = jQuery(this._idElementDom);    
        // On récupère le button d'ajout au panier
        this.elementDomBouton = jQuery(this._elementDom).find(".ui-bouton-valider");
        // et on le désactive
        this.mettreAJourBoutonAjouterPanier(false);
        this.elementDomPrix = jQuery(this._elementDom).find(".ui-groupe-prix");
        // récupération de la devise dans le champ caché
        this.devise = jQuery(this._elementDom).find("input#devise").val();
        // Si l'objet est décliné
        if (this.estDecline) {
            // On récupère les éléments de déclinaisons du DOM
            this.elementDomDeclinaisons = jQuery(this._elementDom).find(".ui-reference");
            this.elementDomSelectMulti = jQuery(this._elementDom).find(".selectMulti");
            // on fait apparaitre les select divisés
            this.elementDomDeclinaisons.addClass("ui-element-hidden");
            this.elementDomSelectMulti.parents("div.ui-element-hidden").removeClass("ui-element-hidden");        
            // donnees = objets Json contenant les informations des différentes déclinaisons
            tableauDeclinaisons = Array();
            jQuery(donnees).each(function () {
                if (this.vendu) {
                    tableauDeclinaisons.push(this.liste_valeurs_declinaison);
                }
            });
            // tableau contenant toutes les déclinaisons possibles
            this.declinaisons = tableauDeclinaisons;
        }
    },
      
    // Méthode de mise à jour des champs select dynamiques
    // l'identifiant du sélecteur qui vient d'être mis à jour est passé en paramètre
    mettreAJourSelectMulti: function(idSelectCourant) {
        var declinaisons = this.declinaisons;
        var elementSelectionnes = this.elementSelectionnes;
        // On va parcourir tous les select dynamiques pour les mettre à jour
        jQuery(this.elementDomSelectMulti).each(function(index) {
            var idSelect = jQuery(this).attr("id");
            // valeur du select qui vient d'être mis à jour
            var valeurSelect = jQuery(this).val();
            // Si l'id du select courant est = au sélect qui vient d'être à jour :
            // on ne fait rien
            if (idSelectCourant != idSelect) {
                // Sinon on récupère la copie du select original que l'on réinjecte
                // Pour supprimer les entrées "option" qui ne sont pas associées
                jQuery(this).html(jQuery("#" + idSelect + "_copie").html());
                // réinkection de la valeur du select
                jQuery(this).val(valeurSelect);
                var selectMiseAjour = this;
                // Pour chaque option on vérifie si elle être conservé
                jQuery(this).children("option").each(function () {      
                    var garder = false;
                    var optionCourante = jQuery(this).val();
                    // Si l'option courante a une valeur vide alors il s'agit
                    // de la première entrée : doit toujours être conservée
                    if (optionCourante != '') {
                        // Sinon on parcourt chaque couple declinaison possible pour vérifier
                        // si l'option en cours fait partie d'une association de déclinaison
                        jQuery(declinaisons).each(function () {
                            var declinaison = this;
                            if (this[index] == optionCourante) {
                                // Pour chaque valeur de déclinaison
                                jQuery(declinaison).each(function(indexValeur) {
                                    var entree = String(this);
                                    if (indexValeur != index) {
                                        // Si la valeur est
                                        // Soit vide (première entrée)
                                        // Soit 'undefined' (pas encore sélectionnée)
                                        // Soit associée
                                        // Alors on garde l'option
                                        if (elementSelectionnes[indexValeur] == entree
                                        || elementSelectionnes[indexValeur] == ''
                                        || typeof elementSelectionnes[indexValeur] == 'undefined') {
                                            garder = true;
                                        }
                                    }
                                });
                            }
                        });
                        // On enlève l'option
                        // si elle ne fait pas parti d'une combinaison possible
                        if (!garder) {
                            jQuery(this).remove();
                        }
                    }
                });
            }
        });
    },
      
    // Méthode permettant de savoir si tous les selecteurs dynamiques sont renseignés
    estSelectionComplete: function () {
        complete = true;
        // Pour chaque selecteur on regarde si une valeur est sélectionnée
        jQuery(this.elementDomSelectMulti).each(function () {
            var valeurSelectionnee = jQuery(this).children("option:selected").val();
            if (valeurSelectionnee == '') {
                complete = false;
            }
        });
        return complete;
    },  
      
    // Méthode permettant de mettre à jour le prix correspondant aux déclinaisons choisies
    mettreAJourPrix: function () {
        // Si la sélection est complète :
        if (this.estSelectionComplete()) {
            var elementSelectionnes = this.elementSelectionnes;
            var objetSelectionne = null;
            // Pour chaque objet de déclinaison contenant le code_produit, le prix, etc...
            jQuery(this.donneesDeclinaisons).each(function () {
                // recherche du prix correspondant aux sélections
                var objetDeclinaison = this;
                var trouve = true;
                // On passe chaque valeur de déclinaison composant l'association
                jQuery(objetDeclinaison.liste_valeurs_declinaison).each(function(index) {
                    var entree = String(this);
                    // on regarde si ça matche avec les valeurs de l'objet courant
                    // à la moindre différence : ce n'est pas l'objet déclinaison sélectionné
                    if (entree != elementSelectionnes[index]) {
                        trouve = false;
                    }           
                });
                if (trouve) {
                    objetSelectionne = objetDeclinaison;
                }
            });
            // mise à jour des propriétés du produit
            this.prixStandard = parseFloat(objetSelectionne.prix_standard);
            this.prixReduit = parseFloat(objetSelectionne.prix_reduit);
            this.stock = objetSelectionne.stock;
            this.estVendu = true;
            this.codeProduit = objetSelectionne.code_produit;

            // On positionne le selection "initial" pour l'ajout au panier
            jQuery(this.elementDomDeclinaisons).find("select#reference").val(this.codeProduit);
            // mettre à jour le prix en affichage
            this.mettreAJourPrixAffichage(this.prixStandard, "span.ui-prix-standard");
            if (this.prixReduit < this.prixStandard) {
                this.mettreAJourPrixAffichage(this.prixReduit, "span.ui-prix-reduit");
            } else {
                // cacher le prix-reduit
                jQuery(this.elementDomPrix).find("span.ui-prix-reduit span").html('');
            }
            this.mettreAJourBoutonAjouterPanier(true);
        } else {
            this.mettreAJourBoutonAjouterPanier(false);
        }
    },
          
    // Mise à jour de l'affichage du prix
    mettreAJourPrixAffichage: function(prix, span) {
        var prixEntier = parseInt(prix);
        jQuery(this.elementDomPrix).find(span + " span.ui-unites").html(prixEntier);
        jQuery(this.elementDomPrix).find(span + " span.ui-separateur-decimalles").html(",");
        jQuery(this.elementDomPrix).find(span + " span.ui-decimalles").html("00");
        if (prixEntier != prix) {
            // récupération des décimales si le prix est à virgule
            var prixString = prix.toString();
            var decimales = prixString.substring(prixString.indexOf(".")+1);
            jQuery(this.elementDomPrix).find(span + " span.ui-decimalles").html(decimales);
        }      
        // Ajout de la devise
        jQuery(this.elementDomPrix).find(span + " span.ui-devise").html(this.devise);
    },
               
    // Méthode permettant d'activer / désactiver le bouton d'ajout au panier
    mettreAJourBoutonAjouterPanier: function(activer) {
        if (activer) {
            jQuery(this.elementDomBouton).removeAttr("disabled");
            jQuery(this.elementDomBouton).css("cursor", "pointer");
        } else {
            jQuery(this.elementDomBouton).attr("disabled", "disabled");
            jQuery(this.elementDomBouton).css("cursor", "auto");
        }
    }
}
/**
 * Wsa_WebService_CodePostal
 *
 * @param string Formulaire : identifiant du formulaire
 * @param string Langue : langue
 * @access public
 * @return void
 */
function Wsa_WebService_CodePostal(formulaire, langue) {
    this.init(formulaire, langue);
}

/**
 * Wsa_WebService_CodePostal
 */   
Wsa_WebService_CodePostal.prototype = {         
    longueurCodePostal:                 5,
    langue:                             "fr",
    messageErreurCodePostalInvalide:    "",
    messageErreurCommunication:         "",
    messageErreurPaysVide:              "",
    pFormulaire:                        null,
    pChampPays:                         null,    
    pChampCodePostal:                   null,
    pChampCommune:                      null,
    pIndicateurAjax:                    null,
    pFenetreErreurCommunication:        null,
    pFenetreErreurCodePostalInvalide:   null,
    pFenetreDebug:                      null,
    pUrlAppelAjax:                      '',
    pTouchesNonSurveillees:             [8, 13, 16, 17, 18, 20, 32, 33, 34, 35, 36, 37, 38, 39, 40, 91, 92, 93, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 144, 145, 186, 187, 188, 189, 190, 191, 192, 222],    
    
    /**
     * Wsa_WebService_CodePostal::init()
     *
     * @param string Formulaire : identifiant du formulaire
     * @access public
     * @return void
     */
    init: function (formulaire, langue) {
        this.pFormulaire  = jQuery(formulaire);
        this.langue = langue;
        if (this.pFormulaire.length === 1) {
            this.pChampPays         = this.pFormulaire.find('.ui-ws-pays').eq(0);            
            this.pChampCodePostal   = this.pFormulaire.find('.ui-ws-codepostal').eq(0);
            this.pChampCommune      = this.pFormulaire.find('.ui-ws-commune').eq(0);
            this.pUrlAppelAjax      = this.pFormulaire.find('.ui-ws-url').eq(0).val();
            if ((this.pChampPays.length === 1) && (this.pChampCodePostal.length === 1) && (this.pChampCommune.length === 1)) {
                this.pInitialiserMessages();
                this.pInitialiserFenetreErreurCommunication();
                this.pInitialiserFenetreErreurCodePostalInvalide();
                this.pInitialiserFenetreDebug();
                this.pInitialiserChampCommune();
                if (this.pChampCommune.val().length > 0) {
                    this.pChampCommune.attr('disabled', '');
                    this.pChampCommune.attr('readonly', 'readonly');
                }
                this.pInitialiserChampPays();
                this.pInitialiserChampCodePostal();
                this.pInitialiserIndicateurAjax();
            }
        }
    },
    
    /**
     * Wsa_WebService_CodePostal::afficherMessageErreurCommunication()
     *
     * @param string Message : message à afficher
     * @access public
     * @return void
     */  
    afficherMessageErreurCommunication: function (message) {
        this.pFenetreErreurCommunication.html(message);
        this.pFenetreErreurCommunication.show();
    },
      
    afficherMessageErreurCodePostalInvalide: function (messages) {
        var html = '';
        jQuery(messages).each(function (index, message) {
            html += '<li>' + message + '</li>';
        });
        this.pFenetreErreurCodePostalInvalide.html(html);
        this.pFenetreErreurCodePostalInvalide.show();
    },
      
    desactiver: function () {
        this.pChampCodePostal.unbind('keyup.ws');
        this.pChampCodePostal.attr("maxlength", "");
        this.pInitialiserChampCommune();
        this.pChampPays.unbind('change.ws');
        this.pChampCommune.attr('disabled', '');
    },
      
    pInitialiserIndicateurAjax: function () {
        var span = jQuery('<span class="ui-ws-indicateur-ajax"><span>Chargement...</span></span>');
        span.hide();
        span.insertAfter(this.pChampCodePostal);
        this.pIndicateurAjax = span;
    },
    
    pInitialiserFenetreDebug: function () {
        var div = jQuery('<div class="ui-ws-debug"></div>');
        div.hide();
        div.insertAfter(this.pFormulaire);
        this.pFenetreDebug = div;
    },
      
    pInitialiserFenetreErreurCommunication: function () {
        var span = jQuery('<span class="ui-ws-fenetre-erreur"></span>');
        span.hide();
        span.insertAfter(this.pChampCommune);
        this.pFenetreErreurCommunication = span;
    },
    
    pInitialiserFenetreErreurCodePostalInvalide: function () {
        var span = this.pChampCodePostal.next('ul.ui-element-erreurs');
        if (!span[0]) {
            span = jQuery('<ul class="ui-element-erreurs"></ul>');
            span.hide();
            span.insertAfter(this.pChampCodePostal);
        }
        this.pFenetreErreurCodePostalInvalide = span;
    },  
      
    pInitialiserChampCommune: function () {
        if (this.pChampCommune.hasClass('ui-select')) {
            var input = jQuery('<input type="texte" value="" />');
            input.attr('name',  this.pChampCommune.attr('name'));  
            input.attr('id',    this.pChampCommune.attr('id'));
            input.attr('class', this.pChampCommune.attr('class'));
            this.pChampCommune.replaceWith(input);
            this.pChampCommune = input;
            this.pChampCommune.removeClass('ui-select');
            this.pChampCommune.addClass('ui-champ');
        }
        this.pChampCommune.attr('disabled', 'disabled');
    },
    
    pInitialiserMessages: function () {
        switch (this.langue) {
        case "de":
        case "de_CH":
            this.messageErreurCodePostalInvalide = "Die eingegebene PLZ ist nicht gültig";
            this.messageErreurCommunication = "Auf Grund eines technischen Problems konnte Ihre PLZ nicht erkannt werden. Bitte geben Sie Ihren Wohnort manuell ein.";
            this.messageErreurPaysVide = "Bitte wählen Sie ein Land aus";
            break;
        //case "fr":
        //case "fr_CH":
        default:
            this.messageErreurCodePostalInvalide = "Le code postal saisi est invalide";
            this.messageErreurCommunication = "En raison d'un problème technique votre code postal n'a pu être reconnu, merci de saisir manuellement votre ville";
            this.messageErreurPaysVide = "Merci de sélectionner un pays";
            break;
        }
    },
    
    pInitialiserChampPays: function () {
        var objetCourant = this,
            codePostal, 
            commune;
        objetCourant.pChampPays.bind('change.ws', function (event) {
            var optionSelectionnee = objetCourant.pChampPays.find('option[selected]'),
                nomPays;
            if (typeof optionSelectionnee.attr('label') !== 'undefined') {
                nomPays = optionSelectionnee.attr('label').toLowerCase();
            } else {
                nomPays = objetCourant.pFormulaire.find('.ui-ws-pays-libelle').val();
            }
            switch (nomPays) {
            case "france":
            case "frankreich":
            case "allemagne":
            case "deutschland":
            case "germany":  
                objetCourant.longueurCodePostal = 5;
                objetCourant.pChampCodePostal.val("");
                objetCourant.pChampCommune.val("");
                objetCourant.pInitialiserChampCommune();
                break;
            case "belgique":
            case "belgium":
            case "autriche":
            case "österreich":
            case "austria":
            case "oesterreich":
            case "suisse":
            case "schweiz":
            case "switzerland":
                objetCourant.longueurCodePostal = 4;
                objetCourant.pChampCodePostal.val("");
                objetCourant.pChampCommune.val("");
                objetCourant.pInitialiserChampCommune();
                break;
            //case "":
            default:
                objetCourant.longueurCodePostal = 5;
                break;
            }
            objetCourant.pChampCodePostal.attr("maxlength", objetCourant.longueurCodePostal);
        });
        codePostal  = objetCourant.pChampCodePostal.val();
        commune     = objetCourant.pChampCommune.val();
        objetCourant.pChampPays.trigger('change.ws');
        if (codePostal !== '') {
            objetCourant.pChampCodePostal.val(codePostal);
        }
        if (commune !== '') {
            objetCourant.pChampCommune.val(commune);
            objetCourant.pChampCommune.attr('disabled', '');
        }
    },
    
    pInitialiserChampCodePostal: function () {
        var objetCourant = this,
            code, 
            codePostalSaisi, 
            paysSaisi, 
            url;
        objetCourant.pChampCodePostal.attr("autocomplete", "off");
        objetCourant.pChampCodePostal.bind('keyup.ws', function (event) {
            code = (event.keyCode ? event.keyCode : event.which);
            codePostalSaisi = objetCourant.pChampCodePostal.val();
            if (codePostalSaisi.length !== objetCourant.longueurCodePostal) {
                objetCourant.pChampCommune.val('');
                objetCourant.pInitialiserChampCommune();
                objetCourant.pFenetreErreurCodePostalInvalide.hide();
            } else {
                if (jQuery.inArray(code, objetCourant.pTouchesNonSurveillees) === -1) {
                    paysSaisi = objetCourant.pChampPays.val();
                    if (paysSaisi === '') {
                        objetCourant.afficherMessageErreurCodePostalInvalide([objetCourant.messageErreurPaysVide]);
                    } else {
                        objetCourant.pChampCodePostal.attr('disabled', 'disabled');
                        objetCourant.pIndicateurAjax.show();
                        objetCourant.pFenetreErreurCodePostalInvalide.hide();
                        objetCourant.pFenetreDebug.hide();
                        url = objetCourant.pUrlAppelAjax + '/pays/' + paysSaisi + '/codePostal/' + codePostalSaisi;
                        jQuery.ajax({
                            url:        url,
                            dataType:   'json',
                            error:      function (jqXHR, textStatus, errorThrown) {
                                objetCourant.afficherMessageErreurCommunication('<p>' + objetCourant.messageErreurCommunication + ' (WJS-' + jqXHR.status + ')</p>');
                                objetCourant.desactiver();
                            },
                            complete:   function () {
                                objetCourant.pChampCodePostal.attr('disabled', '');
                                objetCourant.pIndicateurAjax.hide();
                            },
                            success:    function (donnees) {
                                if (donnees.estEnErreur) {
                                    objetCourant.afficherMessageErreurCommunication('<p>' + objetCourant.messageErreurCommunication + ' (WWS' + donnees.codeErreur + ')</p>');
                                    objetCourant.desactiver();
                                } else {
                                    objetCourant.pChampCodePostal.val(donnees.codePostalTraite);
                                    var communes    = [],
                                        htmlOptions = '',
                                        selecteur;
                                    jQuery.each(donnees.communes, function (cle, value) {
                                        communes.push(value);
                                        htmlOptions += '<option value="' + cle + '" label="' + value + '">' + value + '</option>';
                                    });
                                    if (communes.length > 1) {
                                        selecteur = jQuery('<select>' + htmlOptions + '</select>');
                                        selecteur.attr('name',  objetCourant.pChampCommune.attr('name'));  
                                        selecteur.attr('id',    objetCourant.pChampCommune.attr('id'));
                                        selecteur.attr('class', objetCourant.pChampCommune.attr('class'));
                                        objetCourant.pChampCommune.replaceWith(selecteur);
                                        objetCourant.pChampCommune = selecteur;
                                        objetCourant.pChampCommune.removeClass('ui-champ');
                                        objetCourant.pChampCommune.addClass('ui-select');
                                    } else {
                                        objetCourant.pInitialiserChampCommune();
                                        if (communes.length === 1) {
                                            objetCourant.pChampCommune.val(communes[0]);
                                            objetCourant.pChampCommune.attr('readonly', 'readonly');
                                            objetCourant.pChampCommune.attr('disabled', '');
                                        } else {
                                            objetCourant.afficherMessageErreurCodePostalInvalide([objetCourant.messageErreurCodePostalInvalide]);
                                            objetCourant.pChampCommune.val('');
                                        }
                                    }
                                }
                                if ((donnees.debug === 1) || (donnees.debug === "1") || (donnees.debug === true)) {
                                    objetCourant.pFenetreDebug.html(donnees.messageDebug);
                                    objetCourant.pFenetreDebug.show();
                                }
                            }
                        });    
                    }
                }
            }
        });
    }
};
jQuery(document).ready(function () {
    var W = new Wsa();
    
    // Code Postal
    W.chargerWebServiceCodePostal('form#creation_compte_client');
    W.chargerWebServiceCodePostal('form#edition_compte_client');
    W.chargerWebServiceCodePostal('form#creation_adresse');
    W.chargerWebServiceCodePostal('form#edition_adresse_client');
    
    // Sélecteur déclinaison
    W.chargerSelecteurDeclinaisonProduit();
});

