'use strict';

// Claves para los tipos de datos que registra LocalStorge
var STORAGE_KEYS = {
  LAYOUT_MODE: 'lm',  // Modo de vista
  PAGE_NUMBER: 'pn',  // Numero de pagina
  ANNOTATIONS: 'ann'  // Anotaciones
};

/**
  @class Clase LocalStorage
  @param {LDTronWeb/LDTronMobile} ldReader Instancia del visor segun dispositivo Web o Mobile
  @param {LDTronStorage.Options} options Opciones requeridas, ver LDTronStorage.Options
*/
var LDTronStorage = function Storage(ldReader, options) {
  this.ldReader = ldReader;
  this.options = $.extend(LDTronStorage.Options, options);
  // Instacia de LocalStorage por storageID
  this.init();
  this.localStorage.removeAll();
  this.showViewerLocalStorage();
  this.controlViewerUpdates();
};

/**
 * @class Options para la creacion de la instancia LDTronStorage.
 * @property {string} [storageID="ldtronStorage"] ID del documento para guardar en LocalStorage.
 * @property {numbe} [storageAnnotationsInterval=2000] Frecuencia de comprobacion de cmbio de anotaciones
 */
LDTronStorage.Options = {
  storageID: 'ldtronStorage',
  storageAnnotationsInterval: 2000
};


// Metodos de la clase LocalStorage
LDTronStorage.prototype = {
  init: function () {
    this.localStorage = $.initNamespaceStorage(this.options.storageID).localStorage;
  },


  // Muestra en el visor lo guardado en LocalSorage
  showViewerLocalStorage: function() {
    var me = this;
    var viewer = readerControl.docViewer;
    // Se muestra el modo de vista antes de estar cargado el documento
    viewer.on('beforeDocumentLoaded', function() {
      me.showViewerLayoutMode();
    });
    // Se muestra el numero de pagina y las anotaciones despues de estar cargado el documento
    $(document).on('documentLoaded', function() {
      me.showViewerPageNumber();
      me.showViewerAnnotations();
      $(document).trigger('LDTronStorageReady');
    });
  },


  // Controla los cambios en el visor para guardarlos en LocalStorage
  controlViewerUpdates: function() {
    var me = this;
    var viewer = readerControl.docViewer;
    // Cambio de numero de pagina en el visor
    viewer.on('pageNumberUpdated', function(e, pageNumber) {
      me.saveLocalStoragePageNumber(pageNumber);
    });

    // Cambio de modo de vista en el visor
    viewer.on('displayModeUpdated', function() {
      me.saveLocalStorageLayoutMode();
    });

    // Cambios de anotaciones el visor
    $(document).on('LDTronStorageReady', function() {
      // Se comprueban las modificaciones de anotaciones cada un intervalo de tiempo
      setInterval(function() {
        if (!me.syncronizedAnnot) {
          me.saveLocalStorageAnnotations();
        }
      }, me.options.storageAnnotationsInterval);
    });
  },


  // Guarda en LocalStore el modo de vista del visor
  saveLocalStorageLayoutMode: function() {
    var layoutMode = this.ldReader.getLayoutMode();
    this.setLocalStorage(STORAGE_KEYS.LAYOUT_MODE, layoutMode);
  },


  // Guarda en LocalStorage el numero de la pagina del visor
  saveLocalStoragePageNumber : function(pageNumber) {
    this.setLocalStorage(STORAGE_KEYS.PAGE_NUMBER, pageNumber);
  },


  // Guarda en LocalStore las anotaciones del visor
  saveLocalStorageAnnotations: function() {
    var me = this;
    var annotsStorage = this.getLocalStorage(STORAGE_KEYS.ANNOTATIONS);
    var am = readerControl.docViewer.getAnnotationManager();
    var annotsViewerLength = am.getAnnotationsList().length;
    // Si hay modificaciones en el visor se guarda en LocalStorage
    if (annotsStorage !== null || annotsViewerLength > 0) {
      var annotsViewer = encodeURIComponent(am.exportAnnotations());
      if (annotsStorage !== annotsViewer) {
        me.setLocalStorage(STORAGE_KEYS.ANNOTATIONS, annotsViewer);
        $(document).trigger('LDTronStorageAnnotationsSaved'); // Notifica LocalStorage del cambio
      }
    }
  },


  // Indica al visor el modo de vista de LocalStorage
  showViewerLayoutMode: function () {
    var layoutMode = this.getLocalStorage(STORAGE_KEYS.LAYOUT_MODE);
    this.ldReader.setLayoutMode(layoutMode); // Los valores nulos lo gestiona el visor
    $(document).trigger('LDTronLayoutModeChanged');
  },


  // Indica al visor el numero de pagina de LocalStorage
  showViewerPageNumber: function () {
    var pageNumber = this.getLocalStorage(STORAGE_KEYS.PAGE_NUMBER);
    if (pageNumber === null) {
      pageNumber = 1;
    }
    readerControl.docViewer.setCurrentPage(pageNumber);
    $(document).trigger('LDTronPageNumberChanged');
  },


  // Indica al visor las anotaciones de LocalStorage
  showViewerAnnotations: function() {
    var annotsStorage = this.getLocalStorage(STORAGE_KEYS.ANNOTATIONS);
    if (annotsStorage !== null) {
      readerControl.docViewer.getAnnotationManager().importAnnotations(decodeURIComponent(annotsStorage));
      $(document).trigger('LDTronAnnotationsChanged');
    }
  },


  // Syncronizan anotaciones a LocalStora y al visor
  syncronizedAnnotations: function(annotations) {
    var me = this;

    // Se deshabilia la comprobacion de cambios de anotaciones
    me.syncronizedAnnot = true;
    me.setLocalStorage(STORAGE_KEYS.ANNOTATIONS, annotations);

    var afterDeletedAnnotations = function (annots, callback) {
      var am = readerControl.docViewer.getAnnotationManager();
      setTimeout(function() {
        var annotsList = am.getAnnotationsList();
        if (annotsList.length > 0) {
          afterDeletedAnnotations(annots, callback);
        }
        else {
          callback(annots);
        }
      }, 100);
    };


    // Importacion asicrona de las anotaciones
    var importAnnotations = function (annots) {
      var am = readerControl.docViewer.getAnnotationManager();
      am.importAnnotationsAsync(decodeURIComponent(annots), function(annotationsList) {
        // Se pintan las anotaciones importadas
        am.drawAnnotationsFromList(annotationsList);
        // Se habilita la comprobacion de cambios de anotaciones
        me.syncronizedAnnot = false;
      });
    };


    // Eliminar las anotaciones existentes
    var am = readerControl.docViewer.getAnnotationManager();
    var annotationsList = am.getAnnotationsList();
    am.deleteAnnotations(annotationsList);


    // Importar las nuevas anotaciones despues de estar borradas las anteriores
    afterDeletedAnnotations(annotations, importAnnotations);
  },


  // Guarda en LocalStorage el valor de una clave
  setLocalStorage: function(key, value) {
    return this.localStorage.set(key, value);
  },


  // Devuelve de Localsorage el valor de una clave
  getLocalStorage: function(key) {
    if (this.localStorage.length === 0) {
      return null;
    }
    else {
      var value = undefined;
      try {
        value = this.localStorage.get(key);
      } catch(e) {
        this.init();
      }
      return (typeof value !== 'undefined') ? value : null;
    }
  },
};
