'use strict';

var self          = require('sdk/self'),
    data          = self.data,
    sp            = require('sdk/simple-prefs'),
    prefs         = sp.prefs,
    pageMod       = require('sdk/page-mod'),
    tabs          = require('sdk/tabs'),
    timers        = require('sdk/timers'),
    loader        = require('@loader/options'),
    contextMenu   = require('sdk/context-menu'),
    array         = require('sdk/util/array'),
    {Ci}         = require('chrome'),
    mm            = require('./mm'),
    notifications = require('sdk/notifications'),
    {defer, resolve} = require('sdk/core/promise');

var {Downloads} = require('resource://gre/modules/Downloads.jsm');
var {FileUtils} = require('resource://gre/modules/FileUtils.jsm');

exports.manifest = {
  fullScreen: true
};

exports.inject = (function () {
  let workers = [], callbacks = [];
  pageMod.PageMod({
    include: ['http://*', 'https://*', 'file:///*'],
    contentScriptFile: data.url('./content_script/inject.js'),
    contentScriptWhen: 'start',
    contentStyleFile : data.url('./content_script/inject.css'),
    contentScriptOptions: {
      base: loader.prefixURI + loader.name + '/'
    },
    attachTo: ['top', 'existing'],
    onAttach: function (worker) {
      array.add(workers, worker);
      worker.on('pageshow', function () {array.add(workers, this);});
      worker.on('pagehide', function () {array.remove(workers, this);});
      worker.on('detach', function () {array.remove(workers, this);});
      callbacks.forEach(function (arr) {
        worker.port.on(arr[0], arr[1]);
      });
    }
  });

  return {
    send: function (id, data, global) {
      workers.forEach(function (worker) {
        if (!global && worker.tab !== tabs.activeTab) {
          return;
        }
        if (!worker) {
          return;
        }
        worker.port.emit(id, data);
      });
    },
    receive: function (id, callback) {
      callbacks.push([id, callback]);
      workers.forEach(function (worker) {
        worker.port.on(id, callback);
      });
    }
  };
})();

exports.storage = {
  read: function (id) {
    return (prefs[id] || prefs[id] + '' === 'false') ? (prefs[id] + '') : null;
  },
  write: function (id, data) {
    data = data + '';
    if (data === 'true' || data === 'false') {
      prefs[id] = data === 'true' ? true : false;
    }
    else if (parseInt(data) + '' === data) {
      prefs[id] = parseInt(data);
    }
    else {
      prefs[id] = data + '';
    }
  }
};

exports.tab = {
  open: function (url, inBackground, inCurrent) {
    if (inCurrent) {
      tabs.activeTab.url = url;
    }
    else {
      tabs.open({
        url: url,
        inBackground: typeof inBackground === 'undefined' ? false : inBackground
      });
    }
  }
};

exports.contextMenu = {
  create: function (label, img, arr) {
    function addOne ([title, img, callback]) {
      return contextMenu.Item({
        label: title,
        image: data.url(img),
        contentScript: 'self.on("click", function () {self.postMessage();});',
        onMessage: function () {
          callback();
        }
      });
    }
    contextMenu.Menu({
      label: label,
      image: data.url(img),
      items: arr.map(addOne),
      context: contextMenu.PredicateContext(function (context) {
        return context.documentURL.indexOf('http') !== -1 || context.documentURL.indexOf('file') !== -1;
      })
    });
  }
};

exports.version = function () {
  return self.version;
};

exports.timer = timers;

sp.on('tineye', function () {
  exports.tab.open('https://addons.mozilla.org/en-US/firefox/addon/capture-reverse-image-search/');
});

function notify (text, onClick) {
  if (!sp.prefs.notification) {
    return;
  }
  notifications.notify({
    title: 'Easy Screenshot',
    text,
    iconURL: self.data.url('./icons/64.png'),
    onClick
  });
}


(function (d) {
  mm.connect(function (obj) {
    if (d) {
      d.resolve(obj);
    }
  });

  exports.screenshot = function (left, top, width, height) {
    d = defer();
    mm.emit('screenshot', {left, top, width, height});
    return d.promise;
  };
  exports.download = function (uri, name) {
    let dir = sp.prefs.directory;
    (dir ? resolve(dir) : Downloads.getPreferredDownloadsDirectory())
    .then(path => new FileUtils.File(path))
    .then(file => {
      file.append(name);
      file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
      return Downloads.fetch(uri, file).then(
        () => notify('Saving as "' + file.path + '"', () => file.reveal())
      );
    })
    .catch(e => notify((e.message || e) + ''));
  };
})();
