// +-------------------------------------------------+
// � 2002-2004 PMB Services / www.sigb.net pmb@sigb.net et contributeurs (voir www.sigb.net)
// +-------------------------------------------------+
// $Id: workZone.js,v 1.25 2023/11/10 16:26:08 dbellamy Exp $

define(["dojo/_base/declare", "dojo/topic", "dojo/_base/lang", "dojo/dom-construct", "dijit/form/Button", "dojo/store/Memory", "dojo/data/ObjectStore", "dijit/registry", "dojox/grid/DataGrid", "app/warningMessage", "dojox/widget/Standby"], function(declare, topic, lang, domConstruct, Button, Memory, ObjectStore, registry, DataGrid, warningMessage, Standby) {
    return declare(null, {

        parentNode : null,
        domNode : null,
        msgDiv : null,
        endButton : null,
        documentsGrid : null,
        documentsStore : null,
        documentsMemory : null,
        validateButton : null,
        cancelButton : null,
        standby : null,
        decisionsButtonsContainer : null,

        /** Constructeur initial
         *
         * Création d'une div masquée ratachée à un noeud dom passé en param
         * Initialise la zone de msg en créant une divMsg
         *
         **/
        constructor : function(parentNode) {
            //console.debug('WORKZONE', this);
            topic.subscribe('readerDatas', lang.hitch(this, this.handleEvents));
            topic.subscribe("contentZone", lang.hitch(this, this.handleEvents));
            topic.subscribe("actionZone", lang.hitch(this, this.handleEvents));
            topic.subscribe("reader_rfid", lang.hitch(this, this.handleEvents));
            
            this.parentNode = parentNode;
            this.domNode = domConstruct.create('div', {
                id : 'msgContainer',
                class : 'msgContainer',
                style : {
                    margin : '0 auto',
                    width : '50%',
                    display : 'none'
                }
            }, this.parentNode);
            this.initMsgZone();

        },

        handleEvents : function(evtType, evtArgs) {
            //console.debug('evt received in workZone', evtType, evtArgs);
            switch (evtType) {
            /** loanResponse: Evenement envoyé par la classe readerDatas lorsqu'elle reçoit la réponse du service jsonRpc apres une requete d'emprunt **/
            case 'loanTempResponse' :
                this.treatLoanTempResponse(evtArgs.response);
                break;
            case 'tooManyExplLoan':
                this.tooManyExpl();
                break;
            case 'loanTempDelResponse' :
                this.hideGrid();
                this.hideDecisionButtons();
                this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_place_item_checkout);
                break;
            case 'loanResponse' :
                this.treatLoanResponse(evtArgs.response);
                break;
            case 'gotExplInfos' :
                this.treatGotExplInfos(evtArgs.response);
                break;
            case 'backResponse' :
                this.treatBackResponse(evtArgs.response);
                break;
            case 'noExplBack':
                this.hideGrid();
                this.hideDecisionButtons();
                this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_place_item_checkin);
                break;
            case 'erase':
                this.erase();
                break;
            case 'rfid_remove_standby':
            	this.standby.hide();
            	break;
            	
            }
        },

        /**
         * Fonction d'initialisation de la zone de travail
         */
        initMsgZone : function() {

            this.documentsStore = new ObjectStore({
                objectStore : new Memory({
                    data : []
                })
            });
            this.documentsGrid = new DataGrid({
                store : this.documentsStore,
                escapeHTMLInData: false,
                query : {
                    id : "*"
                },
                structure : [{
                    name : dojoConfig.bibloto.appParams.msg_expl_title,
                    field : "title",
                    editable : false,
                    width : "50%",
                    formatter : this.formatTitle
                }, {
                    name : dojoConfig.bibloto.appParams.msg_expl_statut,
                    field : "status",
                    editable : false,
                    width : "50%",
                    formatter : this.formatStatus
                }],
                autoHeight : true,
            }, domConstruct.create('div', {
                id : 'documentsDatas',
                style : {
                    height : 'auto',
                    width : 'auto'
                }
            }, this.domNode));

            this.documentsGrid.startup();
            this.documentsGrid.domNode.style.display = "none";
            this.documentsGrid.resetDatas = function() {
                this.store.objectStore.data = [];
            };

            this.msgDiv = domConstruct.create('div', {
                id : 'msgDiv',
                style : {
                    margin : '0 auto',
                    width : '50%',

                }
            }, this.domNode);

            this.decisionsButtonsContainer = domConstruct.create('div', {
                id : 'decisionsButtonsContainer'
            }, this.domNode);

            this.validateButton = new Button({
                label : "Valider",
                onClick : lang.hitch(this, this.callAction),
            }, domConstruct.create('div', {
                id : 'validateButton'
            }, this.decisionsButtonsContainer));
            this.validateButton.startup();

            this.cancelButton = new Button({
                label : "Annuler",
                onClick : lang.hitch(this, this.cancel),
            }, domConstruct.create('div', {
                id : 'cancelButton'
            }, this.decisionsButtonsContainer));
            this.cancelButton.startup();

            this.endButton = new Button({
                label : dojoConfig.bibloto.appParams.msg_dialog_exit,
                onClick : lang.hitch(this, this.endAction),
            }, domConstruct.create('div', {
                id : 'workButton'
            }, this.decisionsButtonsContainer));
            this.endButton.startup();

            this.hideDecisionButtons();
        },

        /**
         * Appelée à l'appui sur le bouton terminer
         */
        endAction : function() {
            registry.byId('actionZone').endAction();
            this.hideGrid();
        },

        erase : function() {
            this.hideGrid();
        },

        /**
         * Fonction d'affichage/masquage de la div principale et du datagrid contenant les infos du document courant
         */
        show : function() {
            this.domNode.style.display = "";
        },

        hide : function() {
            this.domNode.style.display = "none";
        },

        showGrid : function() {
            this.documentsGrid.resetDatas();
            this.documentsGrid.domNode.style.display = "";
            this.documentsGrid.render();
        },

        hideGrid : function() {
            this.documentsGrid.domNode.style.display = "none";
            this.documentsGrid.resetDatas();
        },

        /**
         * Cette fonction permet de définir un message dans la div "msgDiv" (en erreur ou non via le 2eme parametre)
         */
        setMsg : function(msg, error) {
            if (this.msgDiv.style.display == "none")
                this.showMessageDiv();
            if (error) {
                msg = "<div class='error_msg'>" + msg + "</div>";
            } else {
                msg = "<div class='action_msg'>" + msg + "</div>";
            }
            this.msgDiv.innerHTML = msg;
        },

        /**
         * Fonction de traitement de la réponse du prêt temporaire
         */
        treatLoanTempResponse : function(response) {
            // Le document est connu, on a une réponse, on peut l'afficher
            if (response.title != "") {
                //TODO Check ici si le status de la réponse est a 0 ou a 1, en fonction de ça ajouter une classe spéciale au status
                var documentsData = {
                    title : response.icondoc + response.title
                };
                //Document non empruntable
                if (response.status == 0) {

                    play_single_sound("audioNOk");
                    documentsData.class = "error";
                    if (dojoConfig.bibloto.appParams.msg_dialog_checkout_no && dojoConfig.bibloto.appParams.msg_dialog_checkout_no_all == 1) {
                    	documentsData.status = dojoConfig.bibloto.appParams.msg_dialog_checkout_no;
                    	this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_checkout_no, true);
                        var warning = new Array();
                        warning.push(dojoConfig.bibloto.appParams.msg_dialog_checkout_no);
                        new warningMessage('enableLoan', warning, 'Informations');
                        
                    } else if (response.message || response.message_quota) {
                        
                    	documentsData.status = response.message;
                        let warning_message = [];
                        if (response.message) {
                            warning_message.push(response.message);
                        }
                        if (response.message_quota) {
                            warning_message.push(response.message_quota);
                        }
                        
                        new warningMessage('enableLoan', warning_message, 'Informations');
                    }
                    this.hideMessageDiv();
                } else {
                    documentsData.status = "Empruntable";
                    documentsData.class = "neutral";
                    //TODO Ajouter un mode pour déclanger l'emprunt automatique
                    //Créer des boutons Emprunter/Annuler ?
                    if (parseInt(dojoConfig.bibloto.appParams.auto_checkout) == 0) {
                        this.callAction();
                    } else {
                        this.showDecisionButtons();
                    }
                    this.hideMessageDiv();
                }
                this.showGrid();
                this.documentsStore.newItem(documentsData);
                this.documentsStore.save();

            } else {//Document inconnu -> affichage d'un message d'erreur
            	var warning = new Array();
			    if (dojoConfig.bibloto.appParams.msg_dialog_checkout_no && dojoConfig.bibloto.appParams.msg_dialog_checkout_no_all == 1) {
			    	this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_checkout_no, true);			       
			    	warning.push(dojoConfig.bibloto.appParams.msg_dialog_checkout_no);			       
			    } else if (response.message) {
			    	warning.push(response.message); 
			    	this.setMsg(response.message, true);
			    } 
			    new warningMessage('enableLoan', warning, 'Informations');				
			    play_single_sound("audioNOk");
			    this.hideGrid();
            }
        },

        /**
         * Fonction de traitement des infos de l'exemplaire retournées par le webService
         */
        treatGotExplInfos : function(response) {
            /**
             * Faire apparaitre la liste contenant les exemplaires présents sur la platine
             * Suivant le status du document (retour possible ou non) afficher les boutons correspondants
             */
            if (response.title != "") {// Le document est connu, on a une réponse, on peu l'afficher
                var documentsData = {
                    title : response.icondoc + response.title
                };
                if (!response.pret_date) {//Document non emprunté donc non rendable
                    documentsData.status = "Document non emprunté";
                    documentsData.class = "error";
                    this.hideMessageDiv();
                } else {
                    documentsData.status = "";
                    //TODO gérer meilleur message ?!
                    documentsData.class = "neutral";
                    //TODO a voir quand on rajoutera un parametre
                    //this.showDecisionButtons();
                    this.hideMessageDiv();
                    this.callAction();
                }
                this.showGrid();
                this.documentsStore.newItem(documentsData);
                this.documentsStore.save();

            } else {//Document inconnu -> affichage d'un message d'erreur
                //TODO correct message
                this.hideGrid();
                play_single_sound("audioNOk");
                this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_item_cb_unknown, true);
            }

        },

        /**
         * Fonction appelée lorsque trop d'exemplaires sont présents sur la platine
         */
        tooManyExpl : function() {
            this.hideGrid();
            this.hideDecisionButtons();
            this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_too_many_items, true);
        },

        /**
         * Fonction d'affichage et de masquage des boutons terminer et annuler
         */
        hideDecisionButtons : function() {
            this.validateButton.domNode.style.display = "none";
            this.cancelButton.domNode.style.display = "none";
            this.endButton.domNode.style.display = "";
        },
        showDecisionButtons : function() {
            this.validateButton.domNode.style.display = "";
            this.cancelButton.domNode.style.display = "";
            this.endButton.domNode.style.display = "none";
        },

        /**
         * Publication d'un event pour la classe readerDatas (elle éxecutera l'action correcte en fonction de son mode courant)
         */
        callAction : function() {
            if (!this.standby) {
                this.standby = new Standby({
                    target : "msgContainer"
                });
            }
            document.body.appendChild(this.standby.domNode);
            this.standby.startup();
            this.standby.show();
            topic.publish('workZone', 'validateAction');
        },
        /**
         * Traitement de la réponse de l'emprunt
         */
        treatLoanResponse : function(response) {
        	if (dojoConfig.bibloto.appParams.rfid_activate == 0 || !dojoConfig.bibloto.appParams.rfid_security_activate){
        		this.standby.hide();
        	}
        	
        	// Le pret a été effectué
            if (response.status == 1) {
                //Passage de la case status contenue dans le datagrid en vert
                this.documentsStore.objectStore.data[0].status = dojoConfig.bibloto.appParams.msg_dialog_checkout_ok;
                this.documentsStore.objectStore.data[0].class = "ok";
                play_single_sound("audioOk");
                //documentsData.statut = "ok";
                this.documentsGrid.render();
                this.hideDecisionButtons();
                this.hideMessageDiv();
            //Response status à 0 (le cas ne devrais jamais arriver (pret tempo effectué avt))
            } else {
                this.documentsStore.objectStore.data[0].status = response.message;
                this.documentsStore.objectStore.data[0].class = "error";
                //documentsData.statut = "ok";
                play_single_sound("audioNOk");
                this.documentsGrid.render();
                if (response.message_quota || response.message_expl_comment) {
                    var warning = new Array();
                    if (response.message_quota)
                        warning.push(response.message_quota);
                    if (response.message_expl_comment)
                        warning.push(response.message_expl_comment);
                    new warningMessage('enableLoan', warning, 'Informations');
                }
            }
            topic.publish('actionZone', 'explLent', {
                response : response
            });
        },

        /**
         * Traitement de la réponse du retour
         */
        treatBackResponse : function(response) {
            this.standby.hide();
            /** status --> 0 --> Erreur dans le retour, stop la lecture, affichage de la popup **/
            if (response.status == 0) {
                play_single_sound("audioNOk");
                //topic.publish('actionZone', 'stopListen');
                if (response.warning_message) {
                    this.setMsg(response.warning_message, true);
                } else {
                    this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_checkout_no, true);
                }
                this.documentsStore.objectStore.data[0].class = "error";
                this.documentsGrid.render();
                //Passage status en erreur
            /** Status 1 --> Prêt ok; affichage du warning si il y'a **/
            } else {
                play_single_sound("audioOk");
                //this.setMsg(dojoConfig.bibloto.appParams.msg_dialog_place_item_checkin);
                topic.publish('actionZone', 'explBack', {
                    response : response
                });
                
                let warning_message = this.formatBackWarningMessage(response);
                if (warning_message) {
                	if (response.nb_jours_retard > 0) {
                    	if (dojoConfig.bibloto.appParams.nb_jours_retard > 0 && response.nb_jours_retard > dojoConfig.bibloto.appParams.nb_jours_retard) {
    	                    topic.publish('actionZone', 'stopListen');
    	                    new warningMessage('enableBack', warning_message, 'Information');
                    	}
                	} else {
	                    topic.publish('actionZone', 'stopListen');
	                    new warningMessage('enableBack', warning_message, 'Information');
                	}
                }
                this.documentsStore.objectStore.data[0].class = "ok";
                this.documentsStore.objectStore.data[0].status = dojoConfig.bibloto.appParams.msg_dialog_checkin_ok;
                //documentsData.statut = "ok";
                this.documentsGrid.render();
                this.hideDecisionButtons();
                this.hideMessageDiv();
            }
        },

        /**
        * Formatage d'un message de warning en fonction de la réponse du WS lors du retour
        */
        formatBackWarningMessage : function(response) {
            let warning_messages = [];
            if(response.message_loc) {
                warning_messages.push(response.message_loc);
            }
            if(response.message_resa) {
                warning_messages.push(response.message_resa);
            }
            if(response.message_retard) {
                warning_messages.push(response.message_retard);
            }
            if(response.message_amende) {
                warning_messages.push(response.message_amende);
            }
            if(response.message_blocage) {
                warning_messages.push(response.message_blocage);
            }
            if(response.message_expl_note && !dojoConfig.bibloto.appParams.checkin_ignore_expl_msg) {
                warning_messages.push(response.message_expl_note);
            }
            let warning_message = warning_messages.join(' ');
            return warning_message;
        },
        
        /**
         * Affichage & masquage de la div contenant les messages d'erreur ou 'poser un documents'
         */
        hideMessageDiv : function() {
            this.msgDiv.style.display = "none";
        },
        showMessageDiv : function() {
            this.msgDiv.style.display = "";
        },

        /**
         * Fonction appelée lors de l'appui sur le bouton annuler (utilisée en mode douchette surtout)
         */
        cancel : function() {
            this.hideGrid();
            this.hideDecisionButtons();
            this.showMessageDiv();
        },
        /**
         * Fonctions de formatage suivant les réponses des prêts ou retours
         * @param {Object} elt
         */
        formatStatus : function(elt) {
            var completeElt = this.grid.store.objectStore.data[0];
            return "<span class='" + completeElt.class + "Status'>" + elt + "</span>";
        },
        formatTitle : function(elt) {
            var completeElt = this.grid.store.objectStore.data[0];
            return "<span class='" + completeElt.class + "Title'>" + elt + "</span>";
        },
        //TODO: Voir pour remplacer le datagrid contenant les infos de l'exemplaire actuellement posé sur la platine
        //par une div ou une <table> html facilement modifiable/stylisable
    });
});
