'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _electron = require('electron');

var _electron2 = _interopRequireDefault(_electron);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _Search = require('./Search');

var _Search2 = _interopRequireDefault(_Search);

var _TexturesGrid = require('./TexturesGrid');

var _TexturesGrid2 = _interopRequireDefault(_TexturesGrid);

var _TagsGrid = require('./TagsGrid');

var _TagsGrid2 = _interopRequireDefault(_TagsGrid);

var _Footer = require('./Footer');

var _Footer2 = _interopRequireDefault(_Footer);

var _Scene = require('./Scene');

var _Scene2 = _interopRequireDefault(_Scene);

var _fsExtra = require('fs-extra');

var _fsExtra2 = _interopRequireDefault(_fsExtra);

var _chokidar = require('chokidar');

var _chokidar2 = _interopRequireDefault(_chokidar);

var _ncp = require('ncp');

var _ncp2 = _interopRequireDefault(_ncp);

var _rimraf = require('rimraf');

var _rimraf2 = _interopRequireDefault(_rimraf);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var TEXTURES_PATH = './assets';
var APP_PATH = _path2.default.join(_electron2.default.remote.app.getAppPath(), '..', '..');

// Chokidar file watchers (tag -> watcher)
var watchers = {};

var Container = function (_Component) {
  _inherits(Container, _Component);

  function Container(props) {
    _classCallCheck(this, Container);

    var _this = _possibleConstructorReturn(this, (Container.__proto__ || Object.getPrototypeOf(Container)).call(this, props));

    _this.componentDidMount = function () {

      var basepath = _electron2.default.remote.app.getAppPath();

      // Create local textures directory if not exists
      if (!_fsExtra2.default.existsSync(TEXTURES_PATH)) {
        _fsExtra2.default.mkdirSync(TEXTURES_PATH);
      }

      // Drag & Drop
      document.ondragover = function (e) {
        e.preventDefault();
      };

      // On drop textures
      document.ondrop = function (e) {
        e.preventDefault();

        var _loop = function _loop(i) {

          var sourcePath = e.dataTransfer.files[i].path.replace(/\\/g, _path2.default.sep);

          // Do nothing if coming from an internal folder
          if (sourcePath.indexOf(basepath) !== -1) {
            return {
              v: void 0
            };
          }

          // Get tag (textures folder)
          var tag = sourcePath.split(_path2.default.sep).pop();

          // If it is a folder..
          if (_fsExtra2.default.lstatSync(sourcePath).isDirectory()) {

            // Ignore already existing tags
            if (_this.state.tags[tag]) {
              return {
                v: void 0
              };
            }

            // Clone directory
            (0, _ncp2.default)(sourcePath, _path2.default.join(TEXTURES_PATH, tag), function (err) {
              if (err) {
                return console.error(err);
              } else {

                // Add watcher to folder
                _this.addWatcher(_path2.default.join(TEXTURES_PATH, tag));
              }
            });
          }
          // If it is a single file..
          else {

              // Put in untagged tag
              if (!_fsExtra2.default.existsSync(_path2.default.join(TEXTURES_PATH, 'untagged'))) {
                _fsExtra2.default.mkdirSync(_path2.default.join(TEXTURES_PATH, 'untagged'));

                // Add watcher to folder
                _this.addWatcher(_path2.default.join(TEXTURES_PATH, 'untagged'));
              }

              _fsExtra2.default.copySync(sourcePath, _path2.default.join(TEXTURES_PATH, 'untagged', _path2.default.basename(sourcePath)));
            }
        };

        for (var i = 0; i < e.dataTransfer.files.length; i++) {
          var _ret = _loop(i);

          if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
        }
      };

      // Load all textures in fs
      var getDirectories = function getDirectories(srcpath) {
        return _fsExtra2.default.readdirSync(srcpath).filter(function (file) {
          return _fsExtra2.default.statSync(_path2.default.join(srcpath, file)).isDirectory();
        });
      };

      getDirectories(TEXTURES_PATH).forEach(function (path) {
        _this.addWatcher(_path2.default.join(TEXTURES_PATH, path));
      });

      // Press Enter to rename texture (Rename mode only)
      document.addEventListener('keyup', _this.onKeyUp, false);
    };

    _this.onKeyUp = function (e) {

      // ENTER to Rename
      if (_this.state.renameSelectedTexture && e.key === 'Enter' && _this.state.filterText.length > 0) {
        var selectedTexture = _this.state.selectedTextures[Object.keys(_this.state.selectedTextures)[0]];
        var newPath = _path2.default.join(TEXTURES_PATH, selectedTexture.tag, _this.state.filterText + '.' + selectedTexture.ext);

        // Remove selected texture
        _this.deleteTexture(selectedTexture.path);

        // Name already existing
        var count = 1;
        while (_fsExtra2.default.existsSync(newPath)) {
          newPath = _path2.default.join(TEXTURES_PATH, selectedTexture.tag, _this.state.filterText + '_' + count + '.' + selectedTexture.ext);
          count++;
        }

        _fsExtra2.default.renameSync(selectedTexture.path, newPath);

        _this.deselectAllTextures();
        _this.setState({ renameSelectedTexture: false });
      }
    };

    _this.addWatcher = function (path) {
      var watcher = _chokidar2.default.watch(path, { ignored: /(^|[\/\\])\../ });

      // Get tag (textures folder)
      var tag = _path2.default.basename(path);

      //watcher.on('all', (event, path) => console.log(event, path));
      watcher.on('add', function (path) {

        var parentFolder = _path2.default.dirname(path).split(_path2.default.sep).pop();

        // Exclude subfolder files && non-images
        if (parentFolder !== tag || path.match(/\.(jpeg|jpg|gif|png)$/i) === null) {
          _fsExtra2.default.unlinkSync(path);
          return;
        }

        // Skip if already existing
        if (_this.state.textures[path] != undefined) {
          return;
        }

        // Push texture
        var textures = _this.state.textures;
        textures[path] = { id: _this.state.textureID, basepath: APP_PATH, path: path, tag: tag, name: _path2.default.parse(path).name, ext: path.split('.').pop() };

        // Push tag
        var tags = _this.state.tags;
        if (!tags[tag]) {
          tags[tag] = [];
        }
        tags[tag].push(textures[path]);

        // Set state
        _this.setState({ tags: tags, textures: textures, textureID: _this.state.textureID + 1 });
      });

      watcher.on('addDir', function (path) {

        // Delete subfolders
        var subfolder = _path2.default.basename(path);
        if (subfolder !== tag) {
          (0, _rimraf2.default)(path, function (err) {
            return console.log(err);
          });
        }
      });

      watcher.on('unlink', function (path) {
        _this.deleteTexture(path);
      });

      // Add watcher
      watchers[tag] = watcher;
    };

    _this.deleteTexture = function (path) {
      var textures = _this.state.textures;

      // Remove from tags
      var tags = _this.state.tags;
      var texture = textures[path];

      if (texture !== undefined) {
        tags[texture.tag].splice(tags[texture.tag].indexOf(texture), 1);

        // Remove from textures
        delete textures[path];

        _this.setState({ tags: tags, textures: textures });
      }
    };

    _this.setFilterText = function (input) {
      _this.setState({ filterText: input });
    };

    _this.setFooterText = function (text) {

      if (text.length === 0 && Object.keys(_this.state.selectedTextures).length > 0) {
        text = Object.keys(_this.state.selectedTextures).length + ' selected';
      }

      _this.setState({ footerText: text });
    };

    _this.onTexturePreview = function (texture) {
      _this.setState({ viewMode: 'preview', texturePreview: texture });
    };

    _this.copyToClipboard = function (texture) {
      //clipboard.writeText(texturePath);
      var img = _electron.nativeImage.createFromPath(texture.path);
      _electron.clipboard.writeImage(img);
      _this.setState({ footerText: 'Copied to clipboard!' });
    };

    _this.goToTag = function (tag) {
      _this.setState({ filterText: tag, viewMode: 'textures' });
    };

    _this.selectTexture = function (texture) {
      var selectedTextures = _this.state.selectedTextures;
      selectedTextures[texture.path] = texture;
      _this.setState({ selectedTextures: selectedTextures });

      // Set text
      _this.setFooterText(Object.keys(selectedTextures).length + ' selected');
    };

    _this.deselectTexture = function (texture) {
      var selectedTextures = _this.state.selectedTextures;
      delete selectedTextures[texture.path];
      _this.setState({ selectedTextures: selectedTextures });

      // Set text
      _this.setFooterText(Object.keys(selectedTextures).length + ' selected');
    };

    _this.deselectAllTextures = function () {
      _this.setState({ selectedTextures: {}, footerText: '' });
    };

    _this.deleteSelectedTags = function () {

      Object.keys(_this.state.selectedTextures).forEach(function (key) {

        // Delete selected texture
        var selectedTexture = _this.state.selectedTextures[key];
        _fsExtra2.default.unlinkSync(selectedTexture.path);
      });

      _this.deselectAllTextures();
    };

    _this.toggleRename = function () {

      if (!_this.state.renameSelectedTexture) {
        _this.setState({ filterText: '' });
      }

      _this.setState({
        renameSelectedTexture: !_this.state.renameSelectedTexture,
        viewMode: 'textures'
      });
    };

    _this.assignTexturesToTag = function (tag) {

      Object.keys(_this.state.selectedTextures).forEach(function (key) {

        // Move selected texture to new path
        var selectedTexture = _this.state.selectedTextures[key];
        _fsExtra2.default.renameSync(selectedTexture.path, _path2.default.join(TEXTURES_PATH, tag, selectedTexture.name + '.' + selectedTexture.ext));
      });

      _this.deselectAllTextures();
      _this.setState({ viewMode: 'textures' });
    };

    _this.openDesktopViewer = function (texture) {
      _electron.shell.openItem(_path2.default.join(texture.basepath, texture.path));
    };

    _this.powerOff = function () {
      window.close();
    };

    _this.addTag = function (tag) {

      if (_this.state.tags[tag] === undefined) {

        // Create Folder
        var path = _path2.default.join(TEXTURES_PATH, tag);
        if (!_fsExtra2.default.existsSync(path)) {
          _fsExtra2.default.mkdirSync(path);
        }

        // Store new tag
        var temp = _this.state.tags;
        temp[tag] = [];

        _this.setState({ tags: temp });

        // Add watcher
        _this.addWatcher(path);
      }
    };

    _this.deleteTag = function (tag) {

      // Close and delete watcher
      watchers[tag].close();
      delete watchers[tag];

      // Delete tag
      var temp = _this.state.tags;
      delete temp[tag];
      _this.setState({ tags: temp });

      // Delete textures associated to tag
      var textures = _this.state.textures;
      Object.keys(textures).forEach(function (texture) {
        if (textures[texture].tag === tag) {
          delete textures[texture];
        }
      });

      _this.setState({ textures: textures });

      // Remove directory
      (0, _rimraf2.default)(_path2.default.join(TEXTURES_PATH, tag), function (err) {
        return console.log(err);
      });
    };

    _this.toggleViewMode = function () {

      var nextViewMode = void 0;

      if (_this.state.viewMode === 'preview') {
        nextViewMode = 'textures';
      } else {
        nextViewMode = _this.state.viewMode === 'textures' ? 'tags' : 'textures';
      }

      _this.setState({
        viewMode: nextViewMode
      });
    };

    _this.state = {
      tags: {}, // { texture }
      textures: {}, // { path, tag }
      footerText: '',
      filterText: '',
      viewMode: 'textures', // textures, tags, preview
      texturePreview: null,
      selectedTextures: {},
      renameSelectedTexture: false,
      textureID: 0
    };

    return _this;
  }

  // Start file watcher


  //----------------------------------ACTIONS----------------------------------\\


  // Select Texture


  // Deselect Texture


  // Deselect All Textures


  // Delete Selected Tags


  // Rename Selected Texture


  // Assign texture(s) to tag


  // Open image viewer


  // Close onion packer


  //------------------------------TAGS MANAGEMENT------------------------------\\


  //---------------------------------VIEW MODE---------------------------------\\


  _createClass(Container, [{
    key: 'render',
    value: function render() {
      var _this2 = this;

      var noTextures = Object.keys(this.state.textures).length === 0;

      // Drag & Drop UI
      var dragDrop = _react2.default.createElement(
        'div',
        { style: dragDropStyle },
        _react2.default.createElement(
          'div',
          null,
          'Drag your assets here!'
        ),
        _react2.default.createElement('div', { className: 'fa fa-chevron-down fontbulger' })
      );

      // Grids
      var texturesGrids = [];
      Object.keys(this.state.tags).sort().forEach(function (tag) {

        var textures = _this2.state.tags[tag];
        textures.slice().sort(function (a, b) {
          return a.name > b.name;
        });
        //console.log(textures);
        texturesGrids.push(_react2.default.createElement(_TexturesGrid2.default, {
          key: tag,
          textures: textures,
          tag: tag,
          selectedTextures: _this2.state.selectedTextures,
          setFooterText: _this2.setFooterText,
          filterText: _this2.state.filterText,
          onTexturePreview: _this2.onTexturePreview,
          copyToClipboard: _this2.copyToClipboard,
          selectTexture: _this2.selectTexture,
          deselectTexture: _this2.deselectTexture,
          openDesktopViewer: _this2.openDesktopViewer
        }));
      });

      // Tags Grid
      var onClickTag = Object.keys(this.state.selectedTextures).length > 0 ? this.assignTexturesToTag : this.goToTag;
      var tagsGrid = _react2.default.createElement(_TagsGrid2.default, {
        tags: this.state.tags,
        filterText: this.state.filterText,
        addTag: this.addTag,
        deleteTag: this.deleteTag,
        onClickTag: onClickTag });

      // 3D Scene
      var scene = _react2.default.createElement(_Scene2.default, { texture: this.state.texturePreview, style: { paddingTop: '0' } });

      var content = void 0;
      switch (this.state.viewMode) {

        case 'textures':
          content = noTextures ? dragDrop : texturesGrids;
          break;

        case 'tags':
          content = tagsGrid;
          break;

        default:
          content = null;
      }

      // Search bar placeholder
      var placeholder = '';
      if (this.state.renameSelectedTexture) {
        placeholder = 'Enter to rename';
      } else if (this.state.viewMode === 'textures') {
        placeholder = 'Type to filter';
      } else if (this.state.viewMode === 'tags') {
        placeholder = 'Press Enter to add tag';
      }

      // Search bar
      var searchBar = _react2.default.createElement(_Search2.default, {
        placeholder: placeholder,
        filterText: this.state.filterText,
        setFilterText: this.setFilterText,
        powerOff: this.powerOff });

      // Footer Cancel Action
      var footerCancelAction = void 0;
      if (this.state.renameSelectedTexture) {
        footerCancelAction = this.toggleRename;
      } else if (Object.keys(this.state.selectedTextures).length > 0) {
        footerCancelAction = this.deselectAllTextures;
      }

      return _react2.default.createElement(
        'div',
        null,
        this.state.viewMode === 'preview' ? scene : null,
        this.state.viewMode === 'preview' ? null : searchBar,
        _react2.default.createElement(
          'div',
          { style: containerStyle },
          content
        ),
        _react2.default.createElement(_Footer2.default, {
          footerText: this.state.footerText,
          toggleViewMode: this.toggleViewMode,
          viewMode: this.state.viewMode,
          showTextureOptions: Object.keys(this.state.selectedTextures).length > 0,
          cancelAction: footerCancelAction,
          deleteSelectedTags: this.deleteSelectedTags,
          toggleRename: this.toggleRename,
          openDesktopViewer: this.openDesktopViewer,
          showRenameButton: !this.state.renameSelectedTexture && Object.keys(this.state.selectedTextures).length === 1,
          showDeleteButton: !this.state.renameSelectedTexture })
      );
    }
  }]);

  return Container;
}(_react.Component);

exports.default = Container;


var containerStyle = {
  width: '100%',
  height: '100%',
  paddingBottom: '50px'
};

var dragDropStyle = {
  position: 'absolute',
  width: '100%',
  top: '150px',
  color: '#a1a1a1',
  fontSize: '25px',
  textAlign: 'center',
  margin: '0 auto',
  opacity: '0.7'
};