/*
 * OutWit Images
 *
 * Copyright (c) OutWit Technologies 2007-2017.
 * All right reserved
 *
 */


/**
 * @fileOverview Extraction manager for OutWit Images
 * @author pr
 */


/**
 * Extraction manager
 *
 * @static
 */
outwitImages.extractControls = {};

/**
 * Load...
 * @static
 */
outwitImages.extractControls.load = function() {
  this.extractorManager = outwitImages.browserControls.extractorManager;

  var defaultBES = outwitKit.DefaultBrowserExtractorService;

/*  this.extractorManager.register("images", defaultBES.extractorObjects["images"],
                  "linksProgress", null,
                  null, null); */
  this.extractorManager.registerDefault("images");
  this.extractorManager.registerDefault("adjacentImages");

  this.extractorManager.setSingleInstance("images", false);
  this.extractorManager.setSingleInstance("adjacentImages", false);

  this.dedup = {};
  this.outputDedup = {};
  this.thumbTimeouts = {};
  this.URLHistoryListeners = {};
  this.currentDecoding = {};

  coreKit.imageDecodeService.respectOriginalRatio = true;

  this.isADupe = function(aBean) {
    var result = typeof(this.dedup[aBean.URI.spec]) != "undefined";
    this.dedup[aBean.URI.spec] = true;
    return result;
  };

  outwitImages.browserControls.browserManager.addEventListener("locationChanged", outwitImages.extractControls.onLocationChange);

  this.start();
};

outwitImages.extractControls.unload = function() {
  outwitImages.browserControls.browserManager.removeEventListener("locationChanged", outwitImages.extractControls.onLocationChange);
  this.stop();
  this.extractorManager.stopAllInstances();
};


outwitImages.extractControls.onLocationChange = function() {
  outwitImages.extractControls.extractorManager.stopInstances("adjacentImages", true);
};


/**
 * Start listening to extracted images
 * @static
 */
outwitImages.extractControls.start = function() {
  this.extractorManager.addProgressListener("images", this.listener);
  this.extractorManager.addProgressListener("adjacentImages", this.adjacentListener);
  this.extractorManager.setAutoRun("images", true);
  this.running = true;
};

outwitImages.extractControls.clear = function() {
  outwitImages.extractControls.stop();
  outwitImages.extractControls.start();
};

/**
 * Stop listening to extracted images
 * @static
 */
outwitImages.extractControls.stop = function() {
//dump("XXXXXXXXXXXXXXXXXXXXXXXX STOP !!!\n");
  this.running = false;
  this.extractorManager.stopInstances("images");
  this.extractorManager.stopInstances("adjacentImages");

  try {
    this.extractorManager.removeProgressListener("images", this.listener);
    this.extractorManager.removeProgressListener("adjacentImages", this.adjacentListener);
  }
  catch(e) {}

  for (var url in this.URLHistoryListeners) {
    outwitKit.URLHistoryService.removeUpdateListenerForURL(this.URLHistoryListeners[url], url);
  }
  this.URLHistoryListeners = {};
  this.dedup = {};
  this.outputDedup = {};
  coreKit.imageDecodeService.stopDecodingBatch(this.currentDecoding);
  this.currentDecoding = {};
  for (var url in this.thumbTimeouts) {
    coreKit.timerService.cancelTimer(this.thumbTimeouts[url]);
  }
  this.thumbTimeouts = {};
  this.extractorManager.setAutoRun("images", false);
};


/**
 *
 */
outwitImages.extractControls.runAdjacentFromGallery = function() {
  if (!this.running) {
    this.extractorManager.addProgressListener("adjacentImages", this.adjacentListener);
  }
  if (optionsCtrl.autoSequences) {
    var items = outwitImages.UIControls.container.thumbs._itemsDisplayed;
    for (var i = 0; i < items.length; ++i) {
      bean = outwitKit.URLHistoryService.getBeanFromString(items[i].mediaUrl, true);
      if (bean.sourceType != "sequences") {
        // XXX should use Math.max(width, height) of current image instead of arbitrary 150 value
        this.extractorManager.getInstanceForCurrentLocation("adjacentImages").fromLink(outwitKit.URLHistoryService.getBeanFromString(items[i].mediaUrl), 150, 150);
      }
    }
  }
};


outwitImages.extractControls.appendImageToContainer = function(anImageBean) {
  var fullRezBean = (anImageBean.fullResolution
                     ? outwitKit.URLHistoryService.getBeanFromString(anImageBean.fullResolution, true)
                     : anImageBean);

//dump("~=~=~=~=~=> APPENDING " + fullRezBean.URI.spec + " " + fullRezBean.width + "x" + fullRezBean.height + " " + anImageBean.sourceType + "\n");

  if (this.outputDedup[fullRezBean.URI.spec]) return;

  this.outputDedup[fullRezBean.URI.spec] = true;

  var newBean = {
    thumb: anImageBean.thumb,
    src: anImageBean.thumb,
    size: fullRezBean.width + "x" + fullRezBean.height,
    mediaUrl: fullRezBean.URI.spec,
		lowResUrl: anImageBean.URI.spec,
    sourceUrl: (anImageBean.sourceURI ? anImageBean.sourceURI : ""),
    filename: fullRezBean.URI.fileName,
    foundIn: anImageBean.sourceType,
    alt: (anImageBean.description ? anImageBean.description : ""),
    type: "image"
  };

  //try to catch it
  if (optionsCtrl.autoCatch && autocatchRule.testRule(newBean)
      && fullRezBean.height >= ow.app.kernel.prefs.getInt("thumbnails.minHeight")
      && fullRezBean.width  >= ow.app.kernel.prefs.getInt("thumbnails.minWidth")  ) {
    coreKit.coreMessager.observe('CATCH', 1, 1, '', newBean);

  }

//dump("DECIDING : " + outwitImages.UIControls.mode + "\n");

  if (outwitImages.UIControls.mode == outwitImages.UIControls.MODE_CATCH) {
    // enqueue
    outwitImages.UIControls.backgroundItems.push(newBean);
  }
  else {
//dump("XXXXXXXXXXXXXXXXXX APPENDING " + newBean.mediaUrl + "\n");
    outwitImages.UIControls.container.appendItem(newBean, true);
  }

  if (optionsCtrl.autoSequences) {
    // XXX should use Math.max(width, height) of current image instead of arbitrary 150 value
    this.extractorManager.getInstanceForCurrentLocation("adjacentImages").fromLink(fullRezBean, 150, 150);
  }
  //  else if (optionsCtrl.autoSequencesAll) {
  //  this.extractorManager.getInstanceForCurrentLocation("adjacentImages").fromLink(fullRezBean);
  //
};


/**
 * The listener for image extractor
 *
 * @static
 */
outwitImages.extractControls.listener = {
  onStart: function() {

  },
  onStop: function() {

  },
  onAbort: function() {

  },
  onProgress: function(aData) {
//    if (!outwitImages.extractControls.isADupe(aData)) {
//dump("===========> EXTRACTED " + aData.URI.spec + " " + aData.lowResolution + " " + aData.fullResolution + " " + aData.width + "\n");
//outwitImages.extractControls.appendImage(aData);
    outwitImages.extractControls.newImage(aData);
//    }
  }
};


/**
 * The listener for adjacent images extractor
 *
 * @static
 */
outwitImages.extractControls.adjacentListener = {
  onStart: function() {

  },
  onStop: function() {

  },
  onAbort: function() {

  },
  onProgress: function(aData) {
//    if (!outwitImages.extractControls.isADupe(aData)) {
//dump("===========> ADJACENT " + aData.URI.spec + "\n");
//outwitImages.extractControls.appendImage(aData);
    var bean = outwitKit.URLHistoryService.getBean(aData, null, true);
    if (typeof(bean.fullResolution) != "undefined") {
      outwitKit.URLHistoryService.setBeanData(aData, "sourceType", "sequences");
    }
    else {
      outwitKit.URLHistoryService.setBeanData(aData, ["sourceType", "fullResolution"], ["sequences", false]);
    }
    outwitImages.extractControls.newImage(aData);
//    }
  }
};


/**
 * Called when a new image arrives
 *
 */
outwitImages.extractControls.newImage = function(aBean) {
  var bean = outwitKit.URLHistoryService.getBean(aBean, null, true);

//dump(" > RECEIVED : " + bean.URI.spec + "\n");

  // dedup
	/*
  if (this.isADupe(bean)) {
//dump("     => DUPLICATE !\n");
    return false;
  }
	*/

  // we have a FR, should never appear but we never know...
  if (bean.lowResolution) {
    return this.newImage(outwitKit.URLHistoryService.getBeanFromString(bean.lowResolution, null, true));
  }


  if (bean.fullResolution) {
    if (typeof(this.thumbTimeouts[bean.fullResolution]) == "number") {
//dump("    => clearing Timeout " + bean.fullResolution + "\n");
      coreKit.timerService.cancelTimer(this.thumbTimeouts[bean.fullResolution]);
      delete this.thumbTimeouts[bean.fullResolution];
    }
    if (this.currentDecoding[bean.fullResolution]) {
//dump("    => Cancelling decode " + bean.fullResolution + "\n");
      coreKit.imageDecodeService.stopDecoding(bean.fullResolution, this.currentDecoding[bean.fullResolution]);
      delete this.currentDecoding[bean.fullResolution];
    }
  }

  var imageURLStr = bean.URI.spec;



  // thumb
  if (!bean.thumb) {
    // small image, don't make thumb
    if (bean.width <= 200 && bean.height <= 200) {
      outwitKit.URLHistoryService.setBeanData(bean, "thumb", imageURLStr);
    }
    else {
      this.thumbTimeouts[imageURLStr] = coreKit.timerService.setTimer((bean.sourceType == "scripts" ? 1000 : 500), null,
          outwitImages.extractControls.makeThumb, null, imageURLStr);
      return;
    }
  }

  if (typeof(this.thumbTimeouts[imageURLStr]) == "number") {
    coreKit.timerService.cancelTimer(this.thumbTimeouts[imageURLStr]);
    delete this.thumbTimeouts[imageURLStr];
  }

  this.updateImage(bean);
};


outwitImages.extractControls.makeThumb = function(imageURLStr) {
  delete outwitImages.extractControls.thumbTimeouts[imageURLStr];
  var bean = outwitKit.URLHistoryService.getBeanFromString(imageURLStr, true);
////dump("    => !!!!!!!!!!!!!!!!!! MAKE THUMB " + imageURLStr + "\n");
  var decodeCallBack = function(result) {
//dump("    => THUMB CREATED " + imageURLStr + "\n");
    if (outwitImages.extractControls.currentDecoding[imageURLStr]) {
      var bean = outwitKit.URLHistoryService.getBeanFromString(imageURLStr, true);
      if (result.type == "image" && result.thumb && typeof(result.width) != "undefined") {
        outwitKit.URLHistoryService.setBeanData(bean,
            ["lastHeadUpdated", "thumb", "mimeType"],
            [Date.now(), result.thumb, result.mimeType]);
        outwitImages.extractControls.updateImage(bean);
      }
      else {
        outwitKit.URLHistoryService.setBeanData(bean,
            ["lastHeadUpdated", "type", "mimeType"],
            [Date.now(), result.type, result.mimeType]);
      }
      delete outwitImages.extractControls.currentDecoding[imageURLStr];
    }
  };
  outwitImages.extractControls.currentDecoding[imageURLStr] = decodeCallBack;
  coreKit.imageDecodeService.getThumb(bean, decodeCallBack, this, 150, 150);
};


/**
 * Called when an image have a thumb
 */
outwitImages.extractControls.updateImage = function(aBean) {
  var bean = outwitKit.URLHistoryService.getBean(aBean, null, true);
//dump("    > UPDATING " + bean.URI.spec + "    " + bean.fullResolution + "\n");

  if (typeof(bean.fullResolution) != "undefined") {
    if (bean.fullResolution) {
      if (typeof(this.thumbTimeouts[bean.fullResolution]) == "number") {
//dump("    => clearing Timeout " + bean.fullResolution + "\n");
        coreKit.timerService.cancelTimer(this.thumbTimeouts[bean.fullResolution]);
        delete this.thumbTimeouts[bean.fullResolution];
      }
      if (this.currentDecoding[bean.fullResolution]) {
//dump("    => Cancelling decode " + bean.fullResolution + "\n");
        coreKit.imageDecodeService.stopDecoding(bean.fullResolution, this.currentDecoding[bean.fullResolution]);
        delete this.currentDecoding[bean.fullResolution];
      }
    }
    this.appendImageToContainer(bean);
		//dump("   => APPENDING TO CONTAINER\n");
  }
  else {
//dump("    => WAITING FOR FULLREZ\n");
    // listen and call updateImage
    var listener = {
      onUpdate: function(anUpdatedBean) {
        if (typeof(anUpdatedBean.fullResolution) != "undefined") {
          outwitImages.extractControls.updateImage(anUpdatedBean);
          outwitKit.URLHistoryService.removeUpdateListenerForURL(listener, anUpdatedBean.URI.spec);
          delete outwitImages.extractControls.URLHistoryListeners[anUpdatedBean.URI.spec];
        }
      }
    };
    this.URLHistoryListeners[bean.URI.spec] = listener;
    outwitKit.URLHistoryService.addUpdateListenerForURL(listener, bean.URI.spec);
  }
};

