/*
 * IMCE Integration by URL
 * Ex-1: http://example.com/imce?app=XEditor|url@urlFieldId|width@widthFieldId|height@heightFieldId
 * Creates "Insert file" operation tab, which fills the specified fields with url, width, height properties
 * of the selected file in the parent window
 * Ex-2: http://example.com/imce?app=XEditor|sendto@functionName
 * "Insert file" operation calls parent window's functionName(file, imceWindow)
 * Ex-3: http://example.com/imce?app=XEditor|imceload@functionName
 * Parent window's functionName(imceWindow) is called as soon as IMCE UI is ready. Send to operation
 * needs to be set manually. See imce.setSendTo() method in imce.js
 */

(function ($) {
  var appFields = {},
    appWindow = (top.appiFrm || window).opener || parent;

  // Execute when imce loads.
  imce.hooks.load.push(function (win) {
    var index = location.href.lastIndexOf('app=');
    if (index == -1) {
      return;
    }
    var data = decodeURIComponent(location.href.substring(index + 4)).split(
      '|'
    );
    var arr,
      prop,
      str,
      func,
      appName = data.shift();
    // Extract fields
    for (var i = 0, len = data.length; i < len; i++) {
      str = data[i];
      if (!str.length) {
        continue;
      }
      if (str.indexOf('&') != -1) {
        str = str.split('&')[0];
      }
      arr = str.split('@');
      if (arr.length > 1) {
        prop = arr.shift();
        appFields[prop] = arr.join('@');
      }
    }
    // Run custom onload function if available
    if (appFields.imceload && (func = isFunc(appFields.imceload))) {
      func(win);
      delete appFields.imceload;
    }
    // Set custom sendto function. appFinish is the default.
    var sendtoFunc = appFields.url ? appFinish : false;
    //check sendto@funcName syntax in URL
    if (appFields.sendto && (func = isFunc(appFields.sendto))) {
      sendtoFunc = func;
      delete appFields.sendto;
    }
    // Check old method windowname+ImceFinish.
    else if (win.name && (func = isFunc(win.name + 'ImceFinish'))) {
      sendtoFunc = func;
    }
    // Highlight file
    if (appFields.url) {
      // Support multiple url fields url@field1,field2..
      if (appFields.url.indexOf(',') > -1) {
        var arr = appFields.url.split(',');
        for (i = 0; i < arr.length; i++) {
          if ($('#' + arr[i], appWindow.document).length) {
            appFields.url = arr[i];
            break;
          }
        }
      }
      var filename = $('#' + appFields.url, appWindow.document).val() || '';
      imce.highlight(filename.substring(filename.lastIndexOf('/') + 1));
    }
    // Set send to
    sendtoFunc && imce.setSendTo(Drupal.t('Insert file'), sendtoFunc);
  });

  // Default sendTo function
  var appFinish = function (file, win) {
    var $doc = $(appWindow.document);
    for (var i in appFields) {
      $doc.find('#' + appFields[i]).val(file[i]);
    }
    if (appFields.url) {
      try {
        $doc
          .find('#' + appFields.url)
          .blur()
          .change()
          .focus();
      } catch (e) {}
    }
    appWindow.focus();
    win.close();
  };

  // Checks if a string is a function name in the given scope.
  // Returns function reference. Supports x.y.z notation.
  var isFunc = function (str, scope) {
    var obj = scope || appWindow;
    var parts = str.split('.'),
      len = parts.length;
    for (var i = 0; i < len && (obj = obj[parts[i]]); i++) {}
    return obj &&
      i == len &&
      (typeof obj == 'function' ||
        (typeof obj != 'string' &&
          !obj.nodeName &&
          obj.constructor != Array &&
          /^[\s[]?function/.test(obj.toString())))
      ? obj
      : false;
  };
})(jQuery);
