var caisse = {
 
    /*
     * Les propriétés suivantes sont gérées dynamiquement :
     * - caissier
     * - numeroFacture
     * - fonctionActive
     * - affichage
     * - bufferCode
     * - bufferQuantite
     * - bufferVente
     * - annulationDemandee
     * - affichageTotal
     */
 
    initialiser: function( caissier, numeroFacture ) {
        "use strict";
        this.caissier = caissier;
        this.numeroFacture = numeroFacture;
        this.initialiserVente();
    },
 
    traiterCle: function( cle ) {
        "use strict";
        if ( cle === "annuler" ) {
            if ( this.annulationDemandee ) {
                this.initialiserVente();
            } else {
                this.annulationDemandee = true;
                this.affichage = "annul.";
            }
        } else if ( this.affichageTotal ) {
            if ( cle === "ok" ) {
                this.initialiserLigneDetail();
            }
        } else {
            this.annulationDemandee = false;
            this.fonctionActive( cle );
        }
    },
 
    saisirCode: function( cle ) {
        "use strict";
        switch( cle ) {
            case "0":
            case "00":
            case "1":
            case "2":
            case "3":
            case "4":
            case "5":
            case "6":
            case "7":
            case "8":
            case "9":
                if ( ( this.bufferCode.length + cle.length ) <= 6 ) {
                    this.bufferCode += cle;
                    this.affichage = this.bufferCode;
                }
                break;
            case "code":
                if ( this.bufferCode.length === 6 ) {
                    this.traiterCode();
                }
                break;
            case "reculer":
                if ( this.bufferCode ) {
                    this.bufferCode = this.bufferCode.slice( 0, -1 );
                    this.affichage = this.bufferCode;
                } else {
                    this.affichage = "code";
                }
                break;
            case "effacer":
                this.effacer();
                break;
            case "total courant":
                if ( this.affichage === "code" ) {
                    this.afficherTotal();
                }
            case "total":
                if ( this.affichage === "code") {
                    // Afficher le total et terminer la vente
                }
            default:
                break;
        }
    },
 
    traiterCode: function() {
        "use strict";
        if ( getProduitPourCode( this.bufferCode ) ) {
            this.fonctionActive = this.saisirQuantite;
            this.affichage = "qte";
        } else {
            this.bufferCode = "";
            this.affichage = "er.code";
        }
    },
 
    saisirQuantite: function( cle ) {
        "use strict";
        switch( cle ) {
            case "0":
            case "00":
                if ( this.bufferQuantite === "" || this.bufferQuantite === "-" ) {
                    break;
                }
            case "1":
            case "2":
            case "3":
            case "4":
            case "5":
            case "6":
            case "7":
            case "8":
            case "9":
                if ( ( this.bufferQuantite.length + cle.length ) <= 3 ) {
                    this.bufferQuantite += cle;
                    this.affichage = this.bufferQuantite;
                }
                break;
            case "-":
                if ( ! this.bufferQuantite ) {
                    this.bufferQuantite += cle;
                }
                break;
            case "qté":
                this.traiterQuantite();
                break;
            case "reculer":
                if ( this.bufferQuantite ) {
                    this.bufferQuantite = this.bufferQuantite.slice( 0, -1 );
                    this.affichage = this.bufferQuantite;
                } else {
                    this.affichage = "qte";
                }
                break;
            case "effacer":
                this.effacer();
                break;
            default:
                break;
        }
    },
 
    traiterQuantite: function() {
        "use strict";
        var quantite = Number( this.bufferQuantite );
        if ( quantite && quantite > -100 && quantite < 100 ) {
            this.ajouterLigneDetail( this.bufferCode, quantite );
            this.initialiserLigneDetail();
        } else {
            this.bufferQuantite = "";
            this.affichage = "er.qte";
        }
    },
 
    ajouterLigneDetail: function( codeProduit, quantite ) {
        "use strict";
        var parametres = { codeProduit: codeProduit, quantite: quantite };
        var ligneDetail = calculerPrixEtTaxes( parametres );
        this.bufferVente.push( ligneDetail );
    },
 
    effacer: function() {
        "use strict";
        if ( ! this.bufferCode ) {
            this.bufferVente.pop();
        }
        this.initialiserLigneDetail();
    },
 
    afficherTotal: function() {
        "use strict";
        this.affichageTotal = true;
        this.affichage = this.calculerTotal();
    },
 
    calculerTotal: function() {
        "use strict";
        var total = 0;
        for ( var i = 0; i < this.bufferVente.length; i++ ) {
            total = normaliserDollarsCents( total + this.bufferVente[ i ].prixTotal );
        }
        return total;
    },
 
    initialiserLigneDetail: function() {
        "use strict";
        this.fonctionActive = this.saisirCode;
        this.affichage = "code";
        this.bufferCode = "";
        this.bufferQuantite = "";
        this.annulationDemandee = false;
        this.affichageTotal = false;
    },
 
    initialiserVente: function() {
        "use strict";
        this.numeroFacture += 1;
        this.initialiserLigneDetail();
        this.bufferVente = [];
    },
 
};
 
function getProduitPourCode( codeProduit ) {
    "use strict";
 
    var catalogueProduits = {
        '119423': { description: 'Craquelins', prix: 2.75, taxable: false },
        '248800': { description: 'Haricots blancs', prix: 2.19, taxable: false },
        '328001': { description: 'Olives farcies', prix: 1.99, taxable: false },
        '376894': { description: 'Moutarde', prix: 1.99, taxable: false },
        '383863': { description: 'Buiscuits', prix: 2.75, taxable: false },
        '435038': { description: 'Huile de tournesol', prix: 4.99, taxable: false },
        '435071': { description: 'Papier aluminium', prix: 5.39, taxable: true },
        '487603': { description: 'Vinaigre balsamique', prix: 7.49, taxable: false },
        '544411': { description: 'Pois verts', prix: 1.79, taxable: false },
        '564369': { description: 'Barres granola', prix: 3.99, taxable: false },
        '570490': { description: 'Essuie-tout', prix: 4.29, taxable: true },
        '584237': { description: 'Balai', prix: 14.69, taxable: true },
        '585578': { description: 'Brosse à vaisselle', prix: 2.29, taxable: true },
        '674385': { description: 'Bouillon', prix: 3.99, taxable: false },
        '728241': { description: 'Cornichons', prix: 2.19, taxable: false },
        '741761': { description: 'Amandes', prix: 3.49, taxable: false },
        '838314': { description: 'Sel', prix: 0.99, taxable: true },
        '867044': { description: 'Ananas dans son jus', prix: 1.25, taxable: false },
        '870326': { description: 'Lasagne', prix: 2.49, taxable: false },
        '901703': { description: 'Barres tendres', prix: 2.49, taxable: false },
        '928045': { description: 'Poivre', prix: 1.99, taxable: false },
        '954339': { description: 'Cornets gaufrés', prix: 3.99, taxable: false },
        '960827': { description: 'Diner Kraft', prix: 1.09, taxable: false },
        '085106': { description: 'Fondue au chocolat', prix: 4.19, taxable: false },
        '091247': { description: 'Détergent à vaisselle', prix: 2.99, taxable: true },
        '049840': { description: 'Café instantanné', prix: 12.99, taxable: false }
    };
 
    var produit = catalogueProduits[ codeProduit ];
    if ( produit === undefined ) {
        return undefined;
    } else {
        return { code: codeProduit, description: produit.description, prix: produit.prix, taxable: produit.taxable };
    }
 
}
 
function calculerPrixEtTaxes( parametres ) {
     "use strict";
     var produit = getProduitPourCode( parametres.codeProduit );
     var quantite = parametres.quantite;
     var prixAvantTaxes = normaliserDollarsCents( quantite * produit.prix );
     var tps = 0;
     var tvq = 0;
     if ( produit.taxable ) {
         tps = normaliserDollarsCents( prixAvantTaxes * 0.05 );
         tvq = normaliserDollarsCents( ( prixAvantTaxes + tps ) * 0.095 );
     }
     var prixTotal = normaliserDollarsCents( prixAvantTaxes + tps + tvq );
     return { produit: produit, quantite: quantite, prixAvantTaxes: prixAvantTaxes, tps: tps, tvq: tvq, prixTotal: prixTotal };
}
 
function normaliserDollarsCents( montant ) {
     "use strict";
     return Number( montant.toFixed( 2 ) );
}
 
function traiterSequence( afficherChaqueEtape ) {
    "use strict";
    var tableau = sequence.split( "," );
    for ( var i = 0; i < tableau.length; i++ ) {
        caisse.traiterCle( tableau[ i ] );
        if ( afficherChaqueEtape ) {
            console.log( "\nClé traitée : " + tableau[ i ] );
            afficherCaisse();
        }
    }
}
 
function afficherCaisse() {
    "use strict";
    console.log( JSON.stringify( caisse, null, 4 ) );
}
 
var sequence = "0,9,1,2,4,7,4,6,code,2,qté,0,9,1,2,4,annuler,7,code,-,1,qté,total courant,ok,annuler,annuler";
console.log( "\nÉtat initial : " );
caisse.initialiser( "Inconnu", 1000 );
afficherCaisse();
traiterSequence( true );