//@include lib_Class.js

/**
 * This class provides basic functionality for sord types.
 *
 * @author MW, ELO Digital Office GmbH
 * @version 1.0
 *
 * @eloas
 * @eloix
 *
 * @requires sol.common.RepoUtils
 * @requires sol.common.Template
 * @requires sol.common.FileUtils
 *
 */
sol.define("sol.common.SordTypeUtils", {
  singleton: true,

  /**
   * Returns the sord types
   * @return {Object}
   */
  getSordTypes: function () {
    var me = this;
    me.logger.enter("getSordTypes", arguments);
    me.readSordTypes();
    me.logger.exit("getSordTypes", me.sordTypesObj);

    return me.sordTypesObj;
  },

  /**
   * @private
   * Reads the sord types
   */
  readSordTypes: function () {
    var me = this,
        sordTypes, i, sordType;

    if (me.sordTypesObj) {
      return;
    }

    sordTypes = ixConnect.ix().checkoutSordTypes(null, Packages.de.elo.ix.client.SordTypeC.mbNoIcons, LockC.NO);

    for (i = 0; i < sordTypes.length; i++) {
      sordType = sordTypes[i];
      me.insertSordTypeIntoCache(sordType.id, sordType.name);
    }
  },

  /**
   * Returns the sord type ID
   * @param {String} name
   * @return {String} Sord type ID
   */
  getSordTypeId: function (name) {
    var me = this;

    me.readSordTypes();
    if (!me.sordTypeExists(name)) {
      throw "Sord type '" + name + "' doesn't exist";
    }
    return parseInt(me.sordTypesObj[name].id, 10);
  },

  /**
   * @private
   * Inserts a sord type into the local sord types cache
   * @param {String} id
   * @param {String} name
   */
  insertSordTypeIntoCache: function (id, name) {
    var me = this,
        kind;

    if (!id) {
      throw "Sord type ID is empty";
    }
    if (!name) {
      return;
    }
    if (!me.sordTypesObj) {
      me.sordTypesObj = {};
      me.folderSordTypeMaxId = 0;
      me.docSordTypeMaxId = 0;
    }

    kind = me.determinateSordTypeKind(id);
    me.sordTypesObj[name] = { id: id, kind: kind };

    if (kind == "FOLDER") {
      if (id > me.folderSordTypeMaxId) {
        me.folderSordTypeMaxId = id;
      }
    } else if (kind == "DOCUMENT") {
      if (id > me.docSordTypeMaxId) {
        me.docSordTypeMaxId = id;
      }
    }
  },

  /**
   * Determinates the sord type kind (folder/document) of a sord type
   * @param {type} id
   * @returns {undefined}
   */
  determinateSordTypeKind: function (id) {
    if (typeof id == "undefined") {
      throw "Sord type ID is empty";
    }

    if (id == "9999") {
      return "REPOSITORY";
    } else if (id <= 253) {
      return "FOLDER";
    } else if (id <= 9998) {
      return "DOCUMENT";
    }
  },

  /**
   * Checks wether a sord type exists
   * @param {String} name
   * @returns {Boolean}
   */
  sordTypeExists: function (name) {
    var me = this;
    return !!me.sordTypesObj[name];
  },

  /**
   * Create sord type
   * @param {String} id ID
   * @param {String} name Name
   * @param {String} kind, e.g. "FOLDER", "DOCUMENT"
   * @param {Array} iconFileDataArray Array of file data for icons
   * @param {Array} disabledIconFileDataArray Array of file data for disabled icons
   * @param {Array} linkIconFileDataArray Array of file data for link icons
   * @param {Array} extensions
   * @param {Array} force Force
   * @return {Boolean} If true the sord type was installed
   */
  createSordType: function (id, name, kind, iconFileDataArray, disabledIconFileDataArray, linkIconFileDataArray, extensions, force) {
    var me = this,
        sordTypes, i;

    me.logger.enter("createSordType", arguments);
    sordTypes = [];

    me.readSordTypes();
    if (!name) {
      throw "Sord type name is empty";
    }
    if (!kind) {
      throw "sord type kind (folder/document) is empty";
    }

    if (me.sordTypeExists(name) && !force) {
      me.logger.debug(["Sord type '{0}' already exists.", name]);
      return false;
    }

    if (!id) {
      switch (kind) {
        case "FOLDER":
          id = me.folderSordTypeMaxId + 1;
          break;

        case "DOCUMENT":
          id = me.docSordTypeMaxId + 1;
          break;

        default:
          throw "Unsupported sord type kind: " + kind;
      }
    }

    if ((kind == "DOCUMENT") && !extensions) {
      throw "config.extensions must not be empty for document types";
    }

    extensions = extensions || [];

    for (i = 0; i < iconFileDataArray.length; i++) {
      sordTypes.push(me.buildSordType(id, name, iconFileDataArray[i], disabledIconFileDataArray[i], linkIconFileDataArray[i], extensions));
    }

    ixConnect.ix().checkinSordTypes(sordTypes, LockC.NO);

    me.insertSordTypeIntoCache(id, name);

    return true;
  },

  /**
   * @private
   * Build sord type
   * @param {String} id
   * @param {String} name
   * @param {de.elo.ix.client.FileData} iconFileData
   * @param {de.elo.ix.client.FileData} disabledIconFileData
   * @param {de.elo.ix.client.FileData} linkIconFileData
   * @param {Array} extensions
   * @return {de.elo.ix.client.SordType}
   */
  buildSordType: function (id, name, iconFileData, disabledIconFileData, linkIconFileData, extensions) {
    var sordType = new SordType();

    if (!id) {
      throw "Sord type ID is empty";
    }
    if (!name) {
      throw "Sord type name is empty";
    }
    if (!iconFileData) {
      throw "Sord type icon file data is empty";
    }
    if (!disabledIconFileData) {
      throw "Sord type disabled icon file data is empty";
    }
    if (!linkIconFileData) {
      throw "Sord type link icon file data is empty";
    }

    sordType.id = new java.lang.Integer(id);
    sordType.name = name;
    sordType.extensions = extensions || [];
    sordType.icon = iconFileData;
    sordType.disabledIcon = disabledIconFileData;
    sordType.workflowIcon = linkIconFileData;

    return sordType;
  },

  sordTypeIconConfigs: {
    bmp: { contentType: "image/bmp", sordTypeZ: Packages.de.elo.ix.client.SordTypeC.mbAllBMP },
    ico: { contentType: "image/x-ico", sordTypeZ: Packages.de.elo.ix.client.SordTypeC.mbAllICO },
    jpg: { contentType: "image/jpeg", sordTypeZ: Packages.de.elo.ix.client.SordTypeC.mbAllJPG },
    png: { contentType: "image/png", sordTypeZ: Packages.de.elo.ix.client.SordTypeC.mbAllPNG }
  },

  sordTypeIconExtensions: ["bmp", "ico", "jpg", "png"],

  /**
   * Export a sord type to the file system
   * @param {Array} names Names of the sord type
   * @param {String} dirPath Path of the destination folder
   */
  exportSordTypes: function (names, dirPath) {
    var me = this,
        name, i, j;

    me.logger.enter("exportSordTypes", arguments);
    if (!names) {
      throw "Sord type names are empty";
    }

    if (!dirPath) {
      throw "config.folderTypesDirPath is empty";
    }

    for (i = 0; i < names.length; i++) {
      name = names[i];
      for (j = 0; j < me.sordTypeIconExtensions.length; j++) {
        me.exportSordType(name, me.sordTypeIconExtensions[j], dirPath, (j == 0));
      }
    }
    me.logger.exit("exportSordTypes");
  },



  /**
   * Export a sord types icons
   * @param {String} name Name of the sord type
   * @param {String} iconExtension Icon extension
   * @param {String} baseDirPath Path of the destination folder
   * @param {Boolean} exportConfig the configuration to a JSON file
   */
  exportSordType: function (name, iconExtension, baseDirPath, exportConfig) {
    var me = this,
        sordTypeId, sordTypeZ, sordTypeKind,
        sordTypeDirPath, sordTypeDir, sordType,
        iconFilePath, disabledIconFilePath, linkIconFilePath,
        configFilePath, config, extensions, i;

    if (!name) {
      throw "Sord type name is empty";
    }

    if (!baseDirPath) {
      throw "Destination folder path is empty";
    }

    sordTypeId = me.getSordTypeId(name);

    sordTypeZ = me.sordTypeIconConfigs[iconExtension].sordTypeZ;

    sordType = ixConnect.ix().checkoutSordTypes([sordTypeId], sordTypeZ, LockC.NO)[0];

    sordTypeKind = me.determinateSordTypeKind(sordType.id);

    sordTypeDirPath = baseDirPath + File.separator + name;
    sordTypeDir = new File(sordTypeDirPath);
    sordTypeDir.mkdirs();

    try {
      iconFilePath = sordTypeDirPath + File.separator + "Icon." + iconExtension;
      sol.common.FileUtils.saveFileData(sordType.icon, iconFilePath);

      disabledIconFilePath = sordTypeDirPath + File.separator + "Disabled icon." + iconExtension;
      sol.common.FileUtils.saveFileData(sordType.disabledIcon, disabledIconFilePath);

      linkIconFilePath = sordTypeDirPath + File.separator + "Link icon." + iconExtension;
      sol.common.FileUtils.saveFileData(sordType.workflowIcon, linkIconFilePath);
    } catch (ex) {
      throw "Can't save entry type '" + name + "' : " + ex;
    }

    if (exportConfig) {
      configFilePath = sordTypeDirPath + File.separator + "config.json";
      extensions = [];
      if (sordType.extensions) {
        for (i = 0; i < sordType.extensions.length; i++) {
          extensions.push(sordType.extensions[i] + "");
        }
      }
      config = {
        id: sordTypeId,
        name: name,
        kind: sordTypeKind,
        extensions: extensions
      };
      sol.common.FileUtils.writeConfigToFile(configFilePath, config);
    }
  },

  /**
   * Set sord type
   * @param {String} objId Object ID
   * @param {String} sordTypeName Sord type name
   */
  setSordType: function (objId, sordTypeName) {
    var me = this,
        sordZ, sord, sordType;

    if (!objId) {
      throw "Object ID is empty";
    }
    if (!sordTypeName) {
      throw "Sord type name is empty";
    }

    sordType = me.getSordTypeId(sordTypeName);

    sordZ = new SordZ(ObjDataC.mbType);
    sord = ixConnect.ix().checkoutSord(objId, sordZ, LockC.NO);
    sord.type = sordType;
    ixConnect.ix().checkinSord(sord, sordZ, LockC.NO);
  }
});