jQuery(function () {



    try {

        sofad.chemins.serviceResumer = '../services_interactivites/resumer.php';
        sofad.chemins.serviceQuiz    = '../services_interactivites/quiz_serveur.php';

        sofad.interactivites = {};
        var widgets    = sofad.interactivites.widgets    = {interactivites: {}};
        var extensions = sofad.interactivites.extensions = {};
        var controleurs = sofad.interactivites.controleurs = {};

        sofad.interactivites.obtientType = function(widget) {
            var classes = widget.noeuds.attr('class').split(' ');
            var matches;
            var type = {type: "", sousType: ""};
            for(var ii=0; ii<classes.length; ++ii) {
                if(matches = classes[ii].match(/^type-(.+)$/)) {
                    type.type = matches[1];
                } else if(matches = classes[ii].match(/^soustype-(.+)$/)) {
                    type.sousType = matches[1];
                }
            }
            return type;
        };

        /* FORMULAIRES */
        widgets.interactivites.Formulaire = (function() {
            var constructeur    = sofad.sousType( sofad.widgets.Widget );
            var proto           = constructeur.prototype;
            proto.requete      = 'body.type-formulaire';
            
            proto.typesEnfants = {sequence: 'sequences.widgets.Sequence', 
                                  questionnaire: 'questionnaires.widgets.Questionnaire'};
            var ext = sofad.sequences.extensions;
            proto.factory( 'sequences.widgets.Sequence',
                           ext.pagination( ext.precSuiv(  sofad.sequences.widgets.Sequence ) ) );
            
            //DEMO Desactiver enregistrements
            var parent_demarre  = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                var that = this;

            };

            return constructeur;
        })();

        /* RESUMER */

        widgets.interactivites.Resumer = (function () {
            //CONSTRUCTEUR
            var parent_constructeur = widgets.interactivites.Formulaire;
            var constructeur = sofad.sousType( parent_constructeur, function() {
                parent_constructeur.apply(this, arguments);
                this.estEnregistre = false;
                for(var ii=0; ii<this.enfants.length; ++ii) {
                    if("Sequence" == this.enfants[ii].nomWidget) {
                        this.sequence = this.enfants[ii];
                    } else if ("Questionnaire" == this.enfants[ii].nomWidget) {
                        this.questionnaire = this.enfants[ii];
                    }
                }
                if(!(('sequence' in this) && ('questionnaire' in this))) {
                    throw sofad.ExceptionAucunSousWidget(this);
                }

                this.controleurs.boutonCorrige    = new (this.factory('interactivites.controleurs.BoutonCorrigeResumer'))   (this.sequence.controleurs.barreNav);
                this.controleurs.boutonReinit     = new (this.factory('interactivites.controleurs.BoutonReinitResumer'))    (this.sequence.controleurs.barreNav);
                this.controleurs.boutonEnregistre = new (this.factory('interactivites.controleurs.BoutonEnregistreResumer'))(this.sequence.controleurs.barreNav);
                this.controleurs.boutonCorrige.noeuds.hide();
                this.controleurs.boutonReinit.noeuds.hide();
                this.controleurs.boutonEnregistre.noeuds.hide();
                var type = sofad.interactivites.obtientType(this);
                if('exercice' == type.sousType) {
                    this.controleurs.boutonEnregistre.noeuds.remove();
                }
            } );
            var proto = constructeur.prototype;
            proto.requete          = 'body.type-resumer:not(.page-demo)';
            proto.prefixeAlias     = 'alias-de-';
            proto.classeBtnInactif = 'inactif';

            //METHODES
            proto.alert = function(m) { alert(m); };
            proto.index = function() { 
                return this.sequence.index;
            };


            proto.iterChamps = function(question_active_seulement) { 
                return new constIterChamps(this, question_active_seulement);
            };


            proto.changeComportement = function(nom_comportement) {
                this.comportement = new (this.comportements[nom_comportement])(this);
            };


            proto.idClient = function() {
                var classes = this.noeuds.attr('class').split(" ");
                for(var ii=0; ii<classes.length; ++ii) {
                    var classe = classes[ii];
                    if(0 === classe.indexOf(this.prefixeAlias)) {
                        return classe.substr(this.prefixeAlias.length);
                    }
                }
                return this.noeuds.attr('id');
            };


            proto.etat = function(mode, f) { //Gestion d'erreur pourrait être faite
                if(!f) f = function(){};
                jQuery.getJSON(sofad.chemins.serviceResumer,
                               {mode: mode, id_client: this.idClient()},
                               function(o) { 
                                   f(o);
                               });
            };

                
            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                var that = this;

                //Fonctionnalité du bouton Corrigé. Doit être mise en place avant le démarrage des questions,
                //afin qu'elles sachent qu'elles ne doivent pas instancier leur propre bouton Corrigé.
                for(var ii=0; ii<this.questionnaire.enfants.length; ++ii) {
                    (function() {
                        var question = that.questionnaire.enfants[ii];
                        var index_question = ii;
                        
                        question.inscritDeclencheurEvent('correction', function(f_corrige_q) {
                            that.controleurs.boutonCorrige.noeuds.bind('click', function() {
                                if(!jQuery(this).is(':visible')) return;
                                else if(index_question != that.index()) return;
                                else if(question.estCorrige()) return;
                                else if(jQuery(this).hasClass(that.classeBtnInactif)) that.alert(sofad.lang('{L:interactivites.resumer_interdiction_corrige}'));
                                else f_corrige_q();
                            });
                        });
                    })();
                }

                parent_demarre.apply(this, arguments);

                this.charge();
            };

            proto.charge = function() {
                var that = this;
                this.etat('statusclient', function(o) {
                    that.changeComportement( o.est_enregistre ? "enregistre": "ouvert" );
                });
            };


            //CONSTRUCTEURS DE PROPRIÉTÉS OBJETS

            var constIterChamps = (function() {
                var constructeur = function(resumer, question_active_seulement) {
                    this.resumer                 = resumer;
                    this.questionActiveSeulement = question_active_seulement;
                    this.indexQuestion           = question_active_seulement ? this.resumer.index() : 0;
                    this.indexChamp              = 0;
                };

                constructeur.prototype = {
                    suivant: function() {
                        for(; this.indexQuestion < this.resumer.questionnaire.enfants.length; ++this.indexQuestion) {
                            var question = this.resumer.questionnaire.enfants[ this.indexQuestion ];
                            for(; this.indexChamp < question.enfants.length; ++this.indexChamp) {
                                var champ = question.enfants[ this.indexChamp ];
                                if('TexteCorrige' == champ.nomWidget) {
                                    ++this.indexChamp;
                                    return champ;
                                }
                            }
                            if(this.questionActiveSeulement) return;
                            this.indexChamp = 0;
                        }
                    },
                    courant: function() {
                        if(this.valide()) return this.resumer.questionnaire.enfants[ this.indexQuestion ].enfants[ this.indexChamp ]; 
                    },
                    valide: function() {
                        return this.questionActiveSeulement ?
                            this.indexChamp >= this.resumer.questionnaire.enfants[ this.indexQuestion ].enfants.length :
                            this.indexQuestion >= this.resumer.questionnaire.enfants.length;
                    }
                };

                return constructeur;
            })();



            proto.comportements = {
                ouvert: (function() {
                    var constructeur = function(resumer) {
                        this.resumer = resumer;

                        /* Ne pas utiliser simplement .noeuds.show(), car on veut qqch de plus subtil.
                           Le CSS doit pouvoir décider de l'affichage ou non d'un bouton lorsqu'il est inactif.
                           Si on utilise show, un attribut style="display:inline" est ajouté au bouton,
                           ce qui prend préséance sur un style CSS .inactif{display: none}. */
                        this.resumer.controleurs.boutonCorrige.noeuds.removeAttr("style");
                        this.resumer.controleurs.boutonReinit.noeuds.hide();
                        this.resumer.controleurs.boutonEnregistre.noeuds.removeAttr("style");

                        this.brancheVerificationPermissionCorrige();
                        this.brancheVerificationPermissionEnregistrer();
                        this.brancheBoutonEnregistrer();
                    };
                    
                    constructeur.prototype = {
                        brancheVerificationPermissionCorrige: function() {
                            var champ;
                            var iter = this.resumer.iterChamps();
                            var that = this;
                            var f_verif = function() {
                                that.verifiePermissionCorrige();
                            };
                            while(champ = iter.suivant()) {
                                champ.noeuds.bind('change.ouvert', f_verif);
                            }
                            this.resumer.sequence.controleurs.btnSuiv.noeuds.bind('click.ouvert', f_verif);
                            this.resumer.sequence.controleurs.btnPrec.noeuds.bind('click.ouvert', f_verif);
                            this.resumer.controleurs.boutonCorrige.noeuds.bind('click.ouvert', f_verif);
                            this.verifiePermissionCorrige();
                        },

                        brancheVerificationPermissionEnregistrer: function() {
                            var that = this;
                            this.resumer.controleurs.boutonCorrige.noeuds.bind('click.ouvert', function() {
                                that.verifiePermissionEnregistrer();
                            });
                            this.verifiePermissionEnregistrer();
                        },

                        brancheBoutonEnregistrer: function() {
                            var that = this;
                            this.resumer.controleurs.boutonEnregistre.noeuds.bind('click.ouvert', function() {
                                if(!jQuery(this).is(':visible')) return;
                                if(jQuery(this).hasClass(that.resumer.classeBtnInactif)) {
                                    return that.resumer.alert(sofad.lang("{L:interactivites.resumer_interdiction_enregistre}"));
                                }
                                that.resumer.etat('insere', function() {
                                    that.resumer.alert(sofad.lang("{L:interactivites.resumer_confirmation_enregistre}"));
                                });
                                var iter = that.resumer.iterChamps();
                                var champ;
                                while(champ = iter.suivant()) champ.noeuds.unbind('change.ouvert');
                                that.resumer.controleurs.boutonCorrige.noeuds.unbind('click.ouvert');
                                that.resumer.controleurs.boutonEnregistre.noeuds.unbind('click.ouvert');
                                that.resumer.sequence.controleurs.btnSuiv.noeuds.unbind('click.ouvert');
                                that.resumer.sequence.controleurs.btnPrec.noeuds.unbind('click.ouvert');

                                that.resumer.changeComportement('enregistre');
                            });
                        },

                        verifiePermissionEnregistrer: function() {
                            for(var ii=0; ii<this.resumer.questionnaire.enfants.length; ++ii) {
                                var question = this.resumer.questionnaire.enfants[ ii ];
                                if(!question.estCorrige()) {
                                    return this.resumer.controleurs.boutonEnregistre.noeuds.addClass(this.resumer.classeBtnInactif);
                                }
                            }
                            return this.resumer.controleurs.boutonEnregistre.noeuds.removeClass(this.resumer.classeBtnInactif);
                        },
                        
                        verifiePermissionCorrige: function () {
                            var champ;
                            var iter = this.resumer.iterChamps(true);

                            if(this.resumer.questionnaire.enfants[ this.resumer.index() ].estCorrige()) {
                                return this.resumer.controleurs.boutonCorrige.noeuds.addClass(this.resumer.classeBtnInactif);
                            }

                            while(champ = iter.suivant()) {
                                if(champ.noeuds[0].value) {
                                    return this.resumer.controleurs.boutonCorrige.noeuds.removeClass(this.resumer.classeBtnInactif);
                                }
                            }
                            
                            return this.resumer.controleurs.boutonCorrige.noeuds.addClass(this.resumer.classeBtnInactif);
                        }
                    };

                    return constructeur;
                })(),


                enregistre: (function() {
                    var constructeur = function(resumer) {
                        this.resumer = resumer;
                        this.resumer.controleurs.boutonCorrige.noeuds.hide();
                        this.resumer.controleurs.boutonReinit.noeuds.removeAttr("style");
                        this.resumer.controleurs.boutonEnregistre.noeuds.hide();

                        this.resumer.questionnaire.reset();
                        for(var ii=0; ii<this.resumer.questionnaire.enfants.length; ++ii) {
                            var question = this.resumer.questionnaire.enfants[ii];
                            if(!question.estCorrige()) question.events.correction.fire();
                        }

                        this.brancheBoutonReinit();
                    };

                    constructeur.prototype = {
                        brancheBoutonReinit: function() {
                            var that = this;
                            this.resumer.controleurs.boutonReinit.noeuds.bind('click.ferme', function() {
                                that.resumer.etat('reinit');
                                that.resumer.controleurs.boutonReinit.noeuds.unbind('click.ferme');
                                that.resumer.questionnaire.reset();
                                that.resumer.sequence.activeSegment(0);
                                that.resumer.changeComportement('ouvert');
                            });
                        }
                    };

                    return constructeur;
                })()
            };




            return constructeur;
        })();


        //Résumer sans enregistrement

        widgets.interactivites.ResumerDemo = (function() {
            var parent_constructeur = widgets.interactivites.Resumer;
            var constructeur = sofad.sousType( parent_constructeur, function() {
                parent_constructeur.apply(this, arguments);

                this.controleurs.boutonReinit.noeuds.remove();
                //this.controleurs.boutonEnregistre.noeuds.remove();
            } );

            var proto = constructeur.prototype;
            proto.requete = 'body.type-resumer.page-demo';

            proto.comportements = {
                ouvert: sofad.sousType(proto.comportements.ouvert)
            };
            
            proto.comportements.ouvert.prototype.verifiePermissionEnregistrer = function() {
                return this.resumer.controleurs.boutonEnregistre.noeuds.addClass(this.resumer.classeBtnInactif);
            };
            
            proto.comportements.ouvert.prototype.brancheBoutonEnregistrer = function() {
                var that = this;
                this.resumer.controleurs.boutonEnregistre.noeuds.bind('click', function() {
                    that.resumer.alert(sofad.lang('{L:interactivites.btn_quiz_demo_inactif}'));
                });
            };

            proto.charge = function() {
                this.changeComportement("ouvert");
            };
           
            return constructeur;
        })();


        /* Client Quiz */

        widgets.RadioQuiz = (function() {
            var constructeur = sofad.sousType( sofad.widgets.Widget );
            var proto = constructeur.prototype;
            proto.requete = 'input:radio';
            proto.images = {
                bon:     sofad.questionnaires.widgets.RadioBon.prototype.imagesCorrige,
                mauvais: sofad.questionnaires.widgets.RadioMauvais.prototype.imagesCorrige
            };
            proto.verrouille = sofad.questionnaires.widgets.RadioBon.prototype.verrouille;

            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                this.parentEvent('correction').subscribe(this.corrige, null, this);
                this.inscritCommeDeclencheurCorrection();
            };


            proto.inscritCommeDeclencheurCorrection = function() {
                if(jQuery('body.sans-correction-immediate').length) return;
                var quiz      = this.widgetParent.widgetParent.widgetParent.widgetParent;
                var type_quiz = sofad.interactivites.obtientType(quiz);
                if('sans-corrige' == type_quiz.sousType) return;
                var that = this;
                this.declencheParentEvent('correction', 
                                          function(fn) {
                                              that.noeuds.bind('click', function() {
                                                  for(var ii = 0; ii < that.widgetParent.enfants.length; ++ii) {
                                                      that.widgetParent.enfants[ii].noeuds.attr("disabled", true);
                                                      //Indicateur de chargement
                                                      if(this == that.widgetParent.enfants[ii].noeuds[0]) {
                                                          jQuery(this).after(sofad.lang(sofad.format(quiz.htmlIndicateurChargement, sofad.chemins.images)));
                                                      }
                                                  }
                                                  //L'effet par defaut du clic sur un bouton radio est de le cocher.
                                                  //Cet effet ne semble cependant pas toujours se realiser avant
                                                  //Les effets personnalises. Je provoque ici l'effet par defaut avant
                                                  //L'execution des effets personnalises.
                                                  this.checked = true;
                                                  //On inscrit le bouton Radio comme provocateur de l'evenement correction,
                                                  //quoiqu'on ne l'invoque pas directement via fn(). On doit passer
                                                  //par la question pour que celle-ci passe la requete au service web et la reponse
                                                  //aux subscribers.
                                                  that.widgetParent.widgetParent.cliqueBoutonCorrige();
                                              });
                                          });
            }


            proto.corrige = function(nom_evenement, corrige) {
                var quiz = this.widgetParent.widgetParent.widgetParent.widgetParent;
                this.noeuds.parent().find(quiz.requeteIndicateurChargement).remove();
                if(this._estCorrige) return;

                var corrige_question = corrige[0].corriges[ this.widgetParent.widgetParent.index() ]; 
                if(undefined === corrige_question) throw "Corrigé non fourni.";
                
                var corrige_radio = corrige_question[ this.noeuds.attr("name") ];
                var images = this.estUneBonneReponse(corrige_radio) ?
                    this.images.bon :
                    this.images.mauvais;

                this.noeuds.before( sofad.lang( sofad.format( 
                    images[ this.noeuds.is(':checked') ? 'coche' : 'nonCoche' ],
                    sofad.chemins.images ) ) );

                if(("feedbackInline" in corrige_radio) && this.noeuds.is(":checked")) {
                    this.widgetParent.afficheFeedbackInline( corrige_radio.feedbackInline );
                }

                this.verrouille();
                this._estCorrige = true;
            };


            proto.estUneBonneReponse = function(corrige_radio) {
                return (corrige_radio.bon && this.noeuds.is(":checked")) ||
                    !corrige_radio.bon && -1 != jQuery.inArray(this.noeuds[0].value, corrige_radio.bonneReponse);
            };

            proto.videChamps = function() {
                this.noeuds[0].checked = false;
            };



            return constructeur;
        })();



        widgets.CaseCocherQuiz = (function () {
            var constructeur = sofad.sousType( widgets.RadioQuiz );
            var proto = constructeur.prototype;
            proto.requete      = "input:checkbox";
            proto.images = {
                bon:     sofad.questionnaires.widgets.CaseBon.prototype.imagesCorrige,
                mauvais: sofad.questionnaires.widgets.CaseMauvais.prototype.imagesCorrige
            };
            proto.verrouille = sofad.questionnaires.widgets.CaseBon.prototype.verrouille;            


            proto.estUneBonneReponse = function(corrige_case) {
                return  (this.noeuds.is(":checked")  &&  corrige_case.bon) ||
                    (!this.noeuds.is(":checked") && !corrige_case.bon);
            };

            proto.inscritCommeDeclencheurCorrection = function() {};

            return constructeur;
        })();



        widgets.QcmruQuiz = (function() {
            var constructeur = sofad.sousType( sofad.questionnaires.widgets.Qcmru );
            constructeur.prototype.typesEnfants = { radio: 'interactivites.widgets.RadioQuiz' };

            constructeur.prototype.afficheFeedbackInline = function(message) {
                this.controleurs.feedbackInline = new (this.factory("interactivites.controleurs.FeedbackInlineQuiz"))(this, [message]);
            };

            constructeur.prototype.videChamps = function() {
                for(var ii= 0; ii < this.enfants.length; ++ii) {
                    this.enfants[ii].videChamps();
                }
            };


            return constructeur;
        })();



        widgets.QcmrmQuiz = (function() {
            var constructeur = sofad.sousType( sofad.questionnaires.widgets.Qcmrm );
            constructeur.prototype.typesEnfants = { caseCocher: 'interactivites.widgets.CaseCocherQuiz' };
            constructeur.prototype.videChamps = widgets.QcmruQuiz.prototype.videChamps;
            return constructeur;
        })();



        widgets.TexteCorrigeQuiz = (function() {
            var constructeur = sofad.sousType( sofad.widgets.Widget);
            var proto = constructeur.prototype;
            proto.requete = "input:text.texte-corrige";
            

            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                this.parentEvent('correction').subscribe(this.corrige, null, this);
            };


            proto.corrige = function(nom_evenement, corrige) {
                if(this._estCorrige) return;

                var corrige_question = corrige[0].corriges[ this.widgetParent.index() ];
                if(undefined === corrige_question) throw "Corrigé non fourni.";
                
                this.corrigeChamp = corrige_question[ this.noeuds.attr("name") ];

                sofad.questionnaires.widgets.TexteCorrige.prototype.corrige.apply(this, []);
            };


            proto.valide = function() {
                if(!this.corrigeChamp.bon) {
                    this.reponsesAcceptees = [this.corrigeChamp.bonneReponse];
                }
                return this.corrigeChamp.bon;
            };

            proto.videChamps = function() {
                this.noeuds[0].value = "";
            };



            return constructeur;
        })();



        widgets.QuestionQuiz = (function() {
            var constructeur = sofad.sousType( sofad.questionnaires.widgets.Question );
            var proto        = constructeur.prototype;
            proto.typesEnfants = {
                qcmru:          'interactivites.widgets.QcmruQuiz',
                qcmrm:          'interactivites.widgets.QcmrmQuiz',
                textesCorriges: 'interactivites.widgets.TexteCorrigeQuiz'
            };

            proto.quiz  = function() {
                return this.widgetParent.widgetParent;
            };

            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                var type_quiz = sofad.interactivites.obtientType(this.quiz());
                if('sans-corrige' == type_quiz.sousType && "boutonCorrige" in this.controleurs) {
                    this.controleurs.boutonCorrige.noeuds.remove();
                }
            };

            proto.index = function() {
                var questionnaire = this.widgetParent;
                for(var ii=0; ii<questionnaire.enfants.length; ++ii) {
                    if(questionnaire.enfants[ii] === this) {
                        return ii;
                    } 
                }
                return -1;
            };


            proto.enregistre = function(fn, emplacement_indicateur) {
                if(!fn) fn = function() {};
                if(this._estCorrige) {
                    fn();
                    return;
                }
                var valeurs = sofad.valeursFormulaire(this.noeuds);
                valeurs.mode      = 'enregistre';
                valeurs.question  = this.index();
                var quiz_parent = this.quiz();
                quiz_parent.service(valeurs, function(reponse) {
                    fn();
                    quiz_parent.metAJourBoutons(reponse);
                }, 
                                    emplacement_indicateur);
            };


            proto.cliqueBoutonCorrige = function() {
                var that = this;
                if(this._estCorrige) {
                    if("blocCorrige" in this.controleurs) {
                        this.controleurs.blocCorrige.noeuds.toggle();
                    }
                    return;
                }
                if('boutonCorrige' in that.controleurs) {
                    var emplacement_indicateur = that.controleurs.boutonCorrige.noeuds;
                    emplacement_indicateur.attr("disabled", true);
                    var ranime_bouton          = function() { emplacement_indicateur.attr("disabled", false); };
                } else {
                    var emplacement_indicateur = null;
                    var ranime_bouton          = function() {};
                }
                this.enregistre(function() {
                    that.quiz().service(
                        { mode:     "corrigeQuestion",
                          question: that.index() },
                        function(corrige) {
                            ranime_bouton();
                            that.appliqueCorrige(corrige);
                        },
                        emplacement_indicateur
                    );
                }, emplacement_indicateur);
            };


            proto.appliqueCorrige = function(corrige) {
                if(!corrige.corriges[ this.index() ]) {
                    return this.quiz().alert(sofad.lang("{L:interactivites.avertissement_correction_echouee}"));
                }
                this._estCorrige = true;
                this.events.correction.fire(corrige);
                this.quiz().metAJourBoutons(corrige);
                if(corrige.corriges[ this.index() ] && 
                   "messageCorrige" in corrige.corriges[ this.index() ]) {
                    this.controleurs.blocCorrige = new (this.factory("interactivites.controleurs.BlocCorrigeQuiz"))(this, [corrige.corriges[ this.index() ].messageCorrige]);
                    this.controleurs.blocCorrige.noeuds.show();
                }
            };

            proto.videChamps = function() {
                for(var ii= 0; ii < this.enfants.length; ++ii) {
                    this.enfants[ii].videChamps();
                }
            };


            return constructeur;
        })();

        
        controleurs.QuizPrecedent = (function() {
            var constructeur = sofad.sousType(sofad.sequences.controleurs.Precedent);
            var proto        = constructeur.prototype;
            proto.requete    = proto.requete;
            proto.html       = proto.html;
            return constructeur;
        })();


        controleurs.QuizSuivant = (function() {
            var constructeur = sofad.sousType(sofad.sequences.controleurs.Suivant);
            var proto        = constructeur.prototype;
            proto.requete    = proto.requete;
            proto.html       = proto.html;
            return constructeur;
        })();


        controleurs.QuizBarreNav = (function() {
            var constructeur = sofad.sousType(sofad.sequences.controleurs.BarreNav);
            constructeur.prototype.insere = function(widget_parent) {
                widget_parent.noeuds.prepend(this.renduHtml());
            };
            return constructeur;
        })();


        controleurs.QuizBarreNavComplement = (function() {
            var constructeur = sofad.sousType(sofad.sequences.controleurs.BarreNav);
            constructeur.prototype.requete = 'div.barre-navigation-bas';
            constructeur.prototype.html    = '<div class="barre-navigation-bas"></div>';
            return constructeur;
        })();

        controleurs.QuizPrecedentComplement = (function() {
            var constructeur = sofad.sousType(sofad.sequences.controleurs.Precedent);
            var proto        = constructeur.prototype;
            proto.html       = proto.html;
            proto.requete    = proto.requete;
            return constructeur;
        })();

        controleurs.QuizSuivantComplement = (function() {
            var constructeur = sofad.sousType(sofad.sequences.controleurs.Suivant);
            var proto        = constructeur.prototype;
            proto.html       = proto.html;
            proto.requete    = proto.requete;
            return constructeur;
        })();


        extensions.quizPrecSuivComplement = function(original) {
            var constructeur = function() {
                original.apply(this, arguments);

                if(undefined === this.controleurs.barreNavComplement) {
                    this.controleurs.barreNavComplement = new (this.factory('interactivites.controleurs.QuizBarreNavComplement'))(this);
                }
                this.controleurs.btnPrecComplement  = new (this.factory('interactivites.controleurs.QuizPrecedentComplement'))(this.controleurs.barreNavComplement);
                this.controleurs.btnSuivComplement  = new (this.factory('interactivites.controleurs.QuizSuivantComplement'))(this.controleurs.barreNavComplement);

                if(1 >= this.enfants.length) { // inutile si on a un seul segment
                    this.controleurs.btnPrecComplement.noeuds.remove();
                    this.controleurs.btnSuivComplement.noeuds.remove();
                }
            };
            
            var proto = sofad.objet(original.prototype);

            var parent_activeSegment = proto.activeSegment;
            proto.activeSegment = function() {
                parent_activeSegment.apply(this, arguments);
                if(0 == this.index || undefined === this.index) {
                    this.controleurs.btnPrecComplement.noeuds.addClass('inactif');
                } else {
                    this.controleurs.btnPrecComplement.noeuds.removeClass('inactif');
                }
                if(this.enfants.length-1 == this.index || undefined === this.index) {
                    this.controleurs.btnSuivComplement.noeuds.addClass('inactif');
                } else {
                    this.controleurs.btnSuivComplement.noeuds.removeClass('inactif');
                }
            };

            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                var that = this;
                this.controleurs.btnPrecComplement.noeuds.click(
                    function() { that.activeSegmentPrecedent(); return false; }
                );

                this.controleurs.btnSuivComplement.noeuds.click(
                    function() { that.activeSegmentSuivant(); return false; } 
                );

                this.controleurs.barreNavComplement.noeuds.append(this.widgetParent.controleurs.boutonCorrection.noeuds);
            };

            constructeur.prototype = proto;

            return constructeur;
        };


        
        widgets.SequenceQuiz = (function() {
            var ext = sofad.sequences.extensions;
            var constructeur =
                ext.pagination(
                    ext.precSuiv( 
                        ext.btnParPage( sofad.sequences.widgets.Sequence ) ) );
            var proto = constructeur.prototype;
            
            proto.classeQuestionRepondue  = "est-repondue";
            proto.classesQuestionCorrigee = ["est-corrigee-mauvaise", "est-corrigee-bonne"];


            var parent_activeSegment = proto.activeSegment;
            proto.activeSegment = function() {
                if(undefined !== this.index && !("correction" in this.widgetParent.controleurs)) {
                    this.widgetParent.enregistreQuestion(this.index);
                }
                if("correction" in this.widgetParent.controleurs) {
                    this.widgetParent.controleurs.correction.noeuds.hide();
                }
                parent_activeSegment.apply(this, arguments);
                this.noeuds[undefined === this.index ? 'addClass' : 'removeClass']('affiche-resultats');
            };


            proto.metAJourBoutons = function(modifications) {
                var remplis = modifications.remplis;
                if(remplis) {
                    for(var question in remplis) {
                        if(remplis[question]) {
                            this.controleurs.boutonsNav[question].noeuds.addClass(this.classeQuestionRepondue);
                        } else {
                            this.controleurs.boutonsNav[question].noeuds.removeClass(this.classeQuestionRepondue);
                        }
                    }
                }

                var corriges = modifications.corriges;
                if(corriges) {
                    for(var question in corriges) {
                        var question_reussie = 1;
                        for(var champ in corriges[question]) {
                            if("messageCorrige" == champ) continue;
                            if(!corriges[question][champ].bon) {
                                question_reussie = 0;
                                break;
                            }
                        }
                        this.controleurs.boutonsNav[question].noeuds.addClass(this.classesQuestionCorrigee[question_reussie]);
                    }
                }
            };

            constructeur.prototype.factory("sequences.controleurs.BarreNav", 
                                          controleurs.QuizBarreNav);
            constructeur.prototype.factory('sequences.controleurs.Precedent', controleurs.QuizPrecedent);
            constructeur.prototype.factory('sequences.controleurs.Suivant',   controleurs.QuizSuivant);
            

            return extensions.quizPrecSuivComplement(constructeur);
        })();



        widgets.interactivites.Quiz2 = (function() {
            var parent_constructeur = widgets.interactivites.Formulaire;
            var constructeur = sofad.sousType( parent_constructeur, function() {
                parent_constructeur.apply(this, arguments);

                for(var ii=0; ii<this.enfants.length; ++ii) {
                    if("Sequence" == this.enfants[ii].nomWidget) {
                        this.sequence = this.enfants[ii];
                    } else if ("Questionnaire" == this.enfants[ii].nomWidget) {
                        this.questionnaire = this.enfants[ii];
                    }
                }
                if(!(('sequence' in this) && ('questionnaire' in this))) {
                    throw sofad.ExceptionAucunSousWidget(this);
                }

                this.controleurs.but          = new (this.factory("interactivites.controleurs.ButQuiz"))(this);
                this.controleurs.boutonLancer = new (this.factory("interactivites.controleurs.BoutonLancerQuiz"))(this.controleurs.but);
                this.controleurs.boutonCorrection = new (this.factory("interactivites.controleurs.BoutonCorrectionQuiz"))(this.sequence.controleurs.barreNav);
                this.controleurs.boutonSuspendre = new (this.factory("interactivites.controleurs.BoutonSuspensionQuiz"))(this.sequence.controleurs.barreNav);
            } );


            var proto     = constructeur.prototype;
            proto.requete = '.type-quiz2';
            proto.requeteLiensSortie = 'a:not(.popup, .aide)';
            proto.htmlIndicateurChargement    = '<img class="indicateur-chargement" alt="{L:questionnaires.enregistre_ajax_encours}" src="{0}ajax-loader.gif" />';
            proto.requeteIndicateurChargement = '.indicateur-chargement';
                
            proto.factory('sequences.widgets.Sequence',      widgets.SequenceQuiz);
            proto.factory('questionnaires.widgets.Question', widgets.QuestionQuiz);
            proto.alert = function(m)   { return alert(m); };
            proto.confirm = function(m, foui, fnon) {
                if(!fnon) fnon = function () {};
                return confirm(m) ? foui() : fnon();
            };


            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                this.sequence.noeuds.hide();
                this.questionnaire.noeuds.hide();

                var that = this;
                this.controleurs.boutonLancer.noeuds.bind("click", function() {
                    if(jQuery('body.page-demo').length) {
                        that.alert(jQuery(this).attr('title'));  
                        return false;  
                    }
                    that.comportement.lance(); return false;
                });
                this.controleurs.boutonCorrection.noeuds.bind("click", function() {
                    that.comportement.correctionQuiz(); return false;
                });
                this.controleurs.boutonSuspendre.noeuds.bind("click", function() {
                    that.comportement.suspend(); return false;
                });

                //Ne pas envoyer le form lorsqu'on appuie sur Entree
                jQuery(document).keypress(function(e) {
                    if(13 == e.which) return false;
                });
                jQuery('textarea').keypress(function(e) {
                    if(13 == e.which) e.stopPropagation();
                });

                this.changeComportement('ferme');
            };


            proto.changeComportement = function(nom_comportement, args) {
                this.comportement = new (this.comportements[nom_comportement])(this, args);
            };


            proto.enregistreQuestion = function(index) {
                this.comportement.enregistreQuestion(index);
            };
            

            proto.metAJourBoutons = function(changements) {
                this.comportement.metAJourBoutons(changements);
            };


            proto.service = function(params, callback, frere_indicateur_chargement) {
                var that = this;                
                var callback_decore;

                if(frere_indicateur_chargement && frere_indicateur_chargement.length) {
                    frere_indicateur_chargement.after(sofad.lang(sofad.format(this.htmlIndicateurChargement, sofad.chemins.images)));
                    callback_decore = function () {
                        frere_indicateur_chargement.parent().find(that.requeteIndicateurChargement).remove();
                        callback.apply(this, arguments);
                    }
                } else {
                    callback_decore = callback;
                }

                params.idQuiz = jQuery('body').attr('id').substr(5);
                jQuery.post(sofad.chemins.serviceQuiz, params, function(reponse) {
                    if(reponse.erreur) {
                        return that.alert(reponse.message);
                    }
                    
                    callback_decore.apply(null, arguments);
                }, "json");
            };

            proto.videChamps = function() {
                for(var ii=0; ii<this.questionnaire.enfants.length; ++ii) {
                    this.questionnaire.enfants[ii].videChamps();
                }
            }
            
            proto.comportements = {
                ferme: (function () {
                    var constructeur = function(quiz) {
                        this.quiz = quiz;
                        this.quiz.questionnaire.noeuds.hide();
                        this.quiz.controleurs.but.noeuds.show();
                        this.quiz.controleurs.boutonCorrection.noeuds.hide();
                        this.quiz.controleurs.boutonSuspendre.noeuds.hide();
                        this.quiz.controleurs.boutonLancer.noeuds.show();
                    };

                    constructeur.prototype = {
                        lance: function() {
                            var that = this;
                            this.quiz.controleurs.boutonLancer.noeuds.attr("disabled", true);
                            this.quiz.service(
                                {mode: 'lance'},
                                function(reponse) {
                                    that.quiz.controleurs.boutonLancer.noeuds.attr("disabled", false);
                                    if(reponse.vide_champs) {
                                        that.quiz.videChamps();
                                    }
                                    if(1 == reponse.est_lance) {
                                        if(reponse.correction_seulement) {
                                            that.lanceCorrectionSeulement(reponse);
                                        } else {
                                            that.lanceReussi(reponse);
                                        }
                                    } else {
                                        that.lanceEchec(reponse.message);
                                    }
                                },
                                this.quiz.controleurs.boutonLancer.noeuds);
                        },

                        lanceReussi: function(reponse) {
                            this.quiz.changeComportement('ouvert', [reponse]);
                            this.quiz.comportement.chargeEtat(reponse);
                        },

                        lanceCorrectionSeulement: function(reponse) {
                            this.quiz.changeComportement('ouvert', [reponse]);
                            this.quiz.comportement.chargeEtat(reponse);
                            this.quiz.changeComportement('corrige', [reponse.message]);
                        },

                        lanceEchec: function(message) {
                            this.quiz.controleurs.but.noeuds.hide();
                            this.quiz.controleurs.boutonLancer.noeuds.hide();
                            this.quiz.controleurs.msgEchec = new (this.quiz.factory("interactivites.controleurs.MsgEchecQuiz"))(this.quiz, message);
                        }
                    };

                    return constructeur;
                })(),


                ouvert: (function() {
                    var constructeur = function(quiz) {
                        this.quiz = quiz;
                        this.quiz.controleurs.but.noeuds.hide();
                        this.quiz.controleurs.boutonLancer.noeuds.hide();
                        this.quiz.controleurs.boutonCorrection.noeuds.show();
                        this.quiz.controleurs.boutonSuspendre.noeuds.hide();
                        this.quiz.sequence.noeuds.show();
                        this.quiz.questionnaire.noeuds.show();
                        this.brancheConfirmationSurSortie();
                        
                    };

                    constructeur.prototype = {
                        brancheConfirmationSurSortie: function() {
                            var that = this;
                            
                            this.quiz.noeuds.find(this.quiz.requeteLiensSortie).bind('click.quiz2', function() {
                                var lien = this;
                                that.quiz.confirm(sofad.lang("{L:interactivites.confirmation_quitter_quiz}"), function() {
                                    window.open(lien.href, lien.target || "_self"); 
                                });
                                return false;
                            });
                            
                            var menu_page = this.quiz.noeuds.find('#pagenav select');
                            if(menu_page.length) {
                                this.fnMenuPage = menu_page[0].onchange;
                                menu_page[0].onchange = null;
                                this.quiz.noeuds.find('#pagenav select').bind('change.quiz2', function() {
                                    that.quiz.confirm(sofad.lang("{L:interactivites.confirmation_quitter_quiz}"), function() {
                                        that.fnMenuPage.apply(this);
                                    });
                                });
                            }
                        },

                        debrancheConfirmationSurSortie: function() {
                            this.quiz.noeuds.find(this.quiz.requeteLiensSortie).unbind('click.quiz2');
                            if(this.fnMenuPage) {
                                this.quiz.noeuds.find('#pagenav select')[0].onchange = this.fnMenuPage;
                            }
                        },

                        enregistreQuestion: function(index, fn, emplacement_indicateur) {
                            this.quiz.questionnaire.enfants[index].enregistre(fn, emplacement_indicateur);
                        },

                        suspend: function() {
                            var that = this;
                            this.quiz.confirm(sofad.lang("{L:interactivites.confirmation_suspension_quiz}"), function() {
                                that.quiz.service({mode: "suspend"},
                                                  function(reponse) {
                                                      if(!reponse.est_suspendu) return that.quiz.alert("Erreur : demande de suspension refusée");
                                                      that.debrancheConfirmationSurSortie();
                                                      that.quiz.changeComportement("ferme");
                                                  });                            
                            });                            
                            return false;
                        },

                        chargeEtat: function(reponse_service) {
                            if("corriges" in reponse_service) {
                                for(var question in reponse_service.corriges) {
                                    this.quiz.questionnaire.enfants[question].appliqueCorrige( reponse_service );
                                }
                            }
                            if(reponse_service.suspension_permise) {
                                this.quiz.controleurs.boutonSuspendre.noeuds.show();
                            }
                        },

                        correctionQuiz: function() {
                            var that = this;
                            var emplacement_indicateur = this.quiz.controleurs.boutonCorrection.noeuds;
                            emplacement_indicateur.attr("disabled", true);
                            var ranime_bouton = function() { emplacement_indicateur.attr("disabled", false); };
                            this.enregistreQuestion( this.quiz.sequence.index, function() {
                                that.quiz.service({mode: "corrigeQuiz"},
                                                  function(reponse) {
                                                      if('sans-corrige' == sofad.interactivites.obtientType(that.quiz).sousType) {
                                                          that.metAJourBoutons(reponse);
                                                      } else {
                                                          that.chargeEtat(reponse); 
                                                      }
                                                      
                                                      ranime_bouton();
                                                      if(reponse.correctionAcceptee) {
                                                          that.debrancheConfirmationSurSortie();
                                                          that.quiz.changeComportement("corrige", [reponse.message]);
                                                      } else {
                                                          that.quiz.alert(reponse.message);
                                                      }
                                                  }, emplacement_indicateur);
                            }, emplacement_indicateur );
                        },

                        metAJourBoutons: function(changements) {
                            this.quiz.sequence.metAJourBoutons(changements);
                        }
                    };

                    return constructeur;
                })(),


                corrige: (function() {
                    var constructeur = function(quiz, args) {
                        this.quiz = quiz;
                        this.quiz.controleurs.boutonSuspendre.noeuds.hide();
                        this.quiz.controleurs.correction = new (this.quiz.factory("interactivites.controleurs.CorrectionQuiz"))(this.quiz.sequence, [args[0]]);
                        for(var nom_widget in sofad.surfenetres.widgets.surfenetres) {
                            var widgets = sofad.batiWidgets( sofad.surfenetres.widgets.surfenetres[ nom_widget ], this.quiz.controleurs.correction.noeuds );
                            for(var ii=0; ii<widgets.length; ++ii) widgets[ii].demarre();
                        }

                        this.quiz.noeuds.find("input").attr("disabled", "disabled");
                        this.correctionQuiz();
                    };

                    constructeur.prototype = {
                        enregistreQuestion: function() {},

                        correctionQuiz: function() {
                            this.quiz.sequence.activeSegment(false);
                            this.quiz.controleurs.correction.noeuds.show();
                        },

                        metAJourBoutons: function(changements) {
                            this.quiz.sequence.metAJourBoutons(changements);
                        }

                    };

                    return constructeur;
                })()
            };


            return constructeur;
        })();


        controleurs.BoutonLancerQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'button.lancer-quiz';
            if(jQuery('body.page-demo').length) {
                constructeur.prototype.html    = sofad.lang("<p class='lancer-quiz'><button title='{L:interactivites.btn_quiz_demo_inactif}' class='lancer-quiz'>{L:interactivites.btn_lancer_quiz}</button></p>");
            } else {
                constructeur.prototype.html    = "<p class='lancer-quiz'><button class='lancer-quiz'>{L:interactivites.btn_lancer_quiz}</button></p>";
            }
            return constructeur;
        })();


        controleurs.BoutonCorrectionQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'button.correction-quiz';
            constructeur.prototype.html    = "<button class='correction-quiz'>{L:interactivites.btn_correction_quiz}</button>";
            return constructeur;
        })();


        controleurs.BoutonSuspensionQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'button.suspension-quiz';
            constructeur.prototype.html    = "<button class='suspension-quiz'>{L:interactivites.btn_suspension_quiz}</button>";
            return constructeur;
        })();


        controleurs.ButQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'div.but';
            constructeur.prototype.html    = "";
            return constructeur;
        })();


        controleurs.CorrectionQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'div.correction-quiz';
            constructeur.prototype.html    = "<div class='correction-quiz'>{0}</div>";
            constructeur.prototype.insere = function(widget_parent) {
                widget_parent.controleurs.barreNav.noeuds.after( this.renduHtml() );
            };
            return constructeur;
        })();


        controleurs.MsgEchecQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'div.msg-echec';
            constructeur.prototype.html    = "<div class='msg-echec'>{0}</div>";
            constructeur.prototype.insere  = function(widget_parent) { widget_parent.questionnaire.noeuds.before(this.renduHtml()); }; 
            return constructeur;
        })();


        controleurs.FeedbackInlineQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'td.feedback-inline > div';
            constructeur.prototype.html    = "<div>{0}</div>";
            constructeur.prototype.insere  = function(widget_parent) { widget_parent.noeuds.find("td.feedback-inline").append(this.renduHtml()); }; 
            return constructeur;
        })();

        controleurs.BlocCorrigeQuiz = (function() {
            var constructeur = sofad.sousType( sofad.controleurs.Controleur );
            constructeur.prototype.requete = 'div.corrige';
            constructeur.prototype.html    = "<div class='corrige'>{0}</div>";
            return constructeur;
        })();
        



        /* QUIZ */

        extensions.radioQuiz = function(original) {
            var constructeur = sofad.questionnaires.extensions.radioFeedback( original );
            constructeur     = sofad.questionnaires.extensions.radioCorrectionImmediate( constructeur );
            constructeur     = sofad.questionnaires.extensions.radioCorrigeEnregistre( constructeur );
            return constructeur;
        };



        widgets.interactivites.QuizApprentissage = (function() {
            ext = sofad.questionnaires.extensions;

            var constr                = ext.enregistreAjax( sofad.widgets.Widget );
            var constructeur          = sofad.sousType(constr, function () {
                constr.apply(this, arguments);
                sofad.chemins.images = '../../../lib-javascript/images/';
            });
            var proto                 = constructeur.prototype;
            proto.requete             = 'body.type-quiz.soustype-apprentissage';
            proto.requeteFormulaire   = 'form:has(input)';
            proto.typesEnfants       = {questionnaire: 'questionnaires.widgets.Questionnaire'};
            proto.htmlImageChargement =  proto.requeteImageChargement = proto.messageEnvoieReussi =  proto.messageEnvoieEchoue = "";

            //Feedback
            proto.factory( 'questionnaires.widgets.RadioBon',
                           extensions.radioQuiz( sofad.questionnaires.widgets.RadioBon ) );
            proto.factory( 'questionnaires.widgets.RadioMauvais',
                           extensions.radioQuiz( sofad.questionnaires.widgets.RadioMauvais ) );
            proto.factory( 'questionnaires.widgets.TexteCorrige',
                           ext.texteCorrigeEnregistre( sofad.questionnaires.widgets.TexteCorrige ) );

            btn_enr = sofad.sousType( sofad.questionnaires.controleurs.BoutonEnregistreAjax );
            btn_enr.prototype.requete = 'input:radio, button.btn-corrige';
            btn_enr.prototype.insere  = function () {};
            proto.factory( 'questionnaires.controleurs.BoutonEnregistreAjax', btn_enr );

            //Attacher au bouton "Corrigé", une fois généré (après démarrage), s'il n'y a pas de bouton radio.
            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                if(!this.controleurs.boutonEnregistreAjax.noeuds.length) {
                    this.controleurs.boutonEnregistreAjax = new (this.factory('questionnaires.controleurs.BoutonEnregistreAjax'))(this);
                    var that = this;
                    this.controleurs.boutonEnregistreAjax.noeuds.bind('click', function() {
                        that.envoieFormulaire();
                    });
                }
            };

            return constructeur;
        })();

        widgets.interactivites.QuizSynthese = (function() {
            ext = sofad.questionnaires.extensions;

            var constr                = ext.enregistreAjax( sofad.widgets.Widget );
            var constructeur          = sofad.sousType(constr, function () {
                constr.apply(this, arguments);
                sofad.chemins.images = '../../../lib-javascript/images/';
            });
            var proto                 = constructeur.prototype;
            proto.requete             = 'body.type-quiz.soustype-synthese';
            proto.requeteFormulaire   = 'form:has(input)';
            proto.typesEnfants       = {};
            proto.htmlImageChargement =  proto.requeteImageChargement = proto.messageEnvoieReussi =  proto.messageEnvoieEchoue = "";

            btn_enr = sofad.sousType( sofad.questionnaires.controleurs.BoutonEnregistreAjax );
            btn_enr.prototype.requete = 'input:radio, input:text';
            btn_enr.prototype.insere  = function () {};
            proto.factory( 'questionnaires.controleurs.BoutonEnregistreAjax', btn_enr );

            return constructeur;
        })();

        
        /* ACTIVITES NOTEES */

        widgets.ChampPointage = (function() {
            var constructeur = sofad.questionnaires.extensions.affichePointageImmediat( sofad.questionnaires.widgets.Element, 'change' );
            var proto     = constructeur.prototype;
            proto.alert   = function(m) { return alert(m); };
            proto.requete = 'input:text.champ-note-partielle';
            proto.requetePonderation = '.note-maximum';
            proto.msgHorsLimite = 'Les notes doivent être comprises entre zéro et leur maximum, sauf pour les bonis.';

            proto.ponderation = function() { 
                return this.noeuds.parent().find(this.requetePonderation).text(); 
            };

            proto.points  = function() {
                var points = [0, Number(this.ponderation())];
                var valeur = this.noeuds[0].value.replace(',', '.');
                if(!isNaN( valeur )) {
                    points[0] = Number(valeur);
                    this.noeuds[0].value = (""+valeur).replace('.', ',');
                }
                return points;
            };

            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                var that = this;
                this.noeuds.bind('change', function() {
                    var points = that.points();
                    if(points[0] < 0 || points[0] > points[1]) {
                        that.alert(that.msgHorsLimite);
                    }
                });
            };

            return constructeur;
        })();


        widgets.QuestionnairePointage = (function() {
            var constructeur = sofad.questionnaires.extensions.affichagePointage( sofad.questionnaires.widgets.Questionnaire );
            var proto = constructeur.prototype;
            proto.typesEnfants = sofad.copie( proto.typesEnfants );
            proto.typesEnfants.champPointage = 'interactivites.widgets.ChampPointage';
            proto.enfantsRequis = false;
            return constructeur;
            
        })();


        widgets.interactivites.ActiviteNotee = (function() {
            var constructeur = sofad.sousType( sofad.widgets.Widget, function() {
                sofad.widgets.Widget.apply(this, arguments);
                this.controleurs.btnTransmettreFmt = new (this.factory('interactivites.controleurs.BoutonTransmettreFmt'))(this);
                this.controleurs.btnTransmettreApp = new (this.factory('interactivites.controleurs.BoutonTransmettreApp'))(this);
                this.estModifie = false;
            } );
            var proto = constructeur.prototype;
            proto.alert   = function(m) { return alert(m); };
            proto.confirm = function(m, foui, fnon) {
                if(!fnon) fnon = function () {};
                return confirm(m) ? foui() : fnon();
            };
            proto.requete = 'body.type-activite-notee';
            proto.typesEnfants = {questionnairePointage: 'interactivites.widgets.QuestionnairePointage'};

            var aff_pt = sofad.sousType( sofad.questionnaires.controleurs.AfficheurPointage );
            aff_pt.prototype.requete = 'input:text.champ-note';
            aff_pt.prototype.insere  = function() {};
            aff_pt.prototype.affiche   = function(pointage) { 
                if(!this.noeuds.length) return;
                this.noeuds[0].value = (""+pointage[0]).replace('.', ',');
            };
            proto.factory( 'questionnaires.controleurs.AfficheurPointage', aff_pt );

            proto.champsVides = function() {
                return this.noeuds.find('textarea, input:text').filter( function() {
                    return ""==this.value;
                });
            };

            var parent_demarre = proto.demarre;
            proto.demarre = function() {
                parent_demarre.apply(this, arguments);
                var that = this;
                this.controleurs.btnTransmettreFmt.noeuds.bind("click", function() {
                    if(!that.champsVides().length) return true;
                    that.alert(sofad.lang("{L:interactivites.activite_notee_questions_vides}"));
                    return false;
                });
                this.controleurs.btnTransmettreApp.noeuds.bind("click", function() {
                    var bouton = jQuery(this);
                    if(bouton.hasClass('confirme') || 
                       !that.noeuds.find('input:text[name$=-fmt-note-partielle]').filter( function() {return ""==this.value;} ).length) return true;
                    
                    that.confirm(sofad.lang("{L:interactivites.activite_notee_notes_vides}"), function() {
                        bouton.addClass('confirme');
                        setTimeout(function() { bouton.click(); }, 10);
                    });
                    return false;
                });

                

                //Bouton Entree - controler le bouton "submit" active si on appuie sur Entree
                jQuery(document).keypress(function(e) {
                    if(e.which != 13 ||
                       that.noeuds.filter('.page-demo').length ||
                       !that.noeuds.find(".btn-enregistrer, .btn-transmettre").length) return;
                    
                    var btns_enregistrer = that.noeuds.find('input:submit[name$=-btn-enregistrer]');
                    if(btns_enregistrer.length) {
                        that.enfants[0].affichePointage();
                        that.noeuds.find('input:submit[name$=-btn-enregistrer]:eq(0)').click();
                    }
                    return false;
                });
                jQuery('textarea').keypress(function(e) {
                    if(13 == e.which) e.stopPropagation();
                });

                //monitorer si l'activite a ete modifiee
                this.noeuds.find("textarea, input:text, input:radio").change(function() {
                    that.estModifie = true;
                });

                this.noeuds.find(".btn-enregistrer, .btn-transmettre").click(function() {
                    that.estModifie = false;
                });

                //avertissement delai
                if(!that.noeuds.filter('.page-demo').length &&
                   that.noeuds.find(".btn-enregistrer, .btn-transmettre").length) {
                    this.chronoAvertissement = setTimeout(function() {
                        that.alert(sofad.lang("{L:interactivites.avertissement_sauvegarde}"));
                    }, 15 * 60 * 1000);
                }

            };

            return constructeur;
        })();


        //Controleurs

        controleurs.BoutonTransmettreFmt = (function () {
            var constructeur = sofad.sousType(sofad.controleurs.Controleur);
            constructeur.prototype.requete   = '*[name$=-btn-transmettre-vers-fmt]';
            constructeur.prototype.html      = '';
            constructeur.prototype.insere    = function(widget_parent) {};
            return constructeur;
        })();

        controleurs.BoutonTransmettreApp = (function () {
            var constructeur = sofad.sousType(controleurs.BoutonTransmettreFmt);
            constructeur.prototype.requete   = '*[name$=-btn-transmettre-vers-app]';
            return constructeur;
        })();

        controleurs.BoutonCorrigeResumer = (function () {
            var constructeur = sofad.sousType(sofad.controleurs.Controleur);
            constructeur.prototype.requete   = 'button.btn-corrige-resumer';
            constructeur.prototype.html      = '<button class="btn-corrige-resumer">{L:interactivites.resumer_btn_corrige}</button>';
            constructeur.prototype.insere  = function(widget_parent) {
                widget_parent.noeuds.prepend( this.renduHtml() );
            };
            return constructeur;
        })();


        controleurs.BoutonEnregistreResumer = (function () {
            var constructeur = sofad.sousType(sofad.controleurs.Controleur);
            constructeur.prototype.requete   = 'button.btn-enregistre-resumer';
            constructeur.prototype.html      = '<button class="btn-enregistre-resumer">{L:interactivites.resumer_btn_enregistre}</button>';
            constructeur.prototype.insere  = function(widget_parent) {
                widget_parent.noeuds.prepend( this.renduHtml() );
            };
            return constructeur;
        })();



        controleurs.BoutonReinitResumer = (function () {
            var constructeur = sofad.sousType(sofad.controleurs.Controleur);
            constructeur.prototype.requete   = 'button.btn-reinit-resumer';
            constructeur.prototype.html      = '<button class="btn-reinit-resumer">{L:interactivites.resumer_btn_reinit}</button>';
            constructeur.prototype.insere  = function(widget_parent) {
                widget_parent.noeuds.prepend( this.renduHtml() );
            };
            return constructeur;
        })();



    } catch(e) {
        if(e.name && 'AucunSousWidget' == e.name) {
            sofad.exposeExceptionAucunSousWidget(e);
        } else {
            alert("exception : " + e);
        }
    }
});
