/* If shouldClip is true, the image will be clipped and resized to the active layer. If shouldClip is false, the image will be inserted before the active layer and resized to the doc width if it's wider. */
var insertImage = function(path, shouldClip, photoTitle) {
  if (app.documents.length != 0) {
    openImageInActiveDoc(path, shouldClip, photoTitle);
  } else {
    openImageInNewDoc(path, photoTitle);
  }
};

var openImageInActiveDoc = function(path, shouldClip, photoTitle) {
  var activeDoc = app.activeDocument;
  var activeLayer = activeDoc.activeLayer;

  activeLayerBounds = getBounds(activeLayer);
  if (shouldClip && (activeLayerBounds.width === 0 || activeLayerBounds.height === 0)) {
    shouldClip = false;
  }

  var newLayer = insertImageToActiveDoc(path, shouldClip, photoTitle);

  if (shouldClip) {
    centerImageInLayer(newLayer, activeLayer);
    createClippingMask();
  }
};

var openImageInNewDoc = function(path, photoTitle) {
  openNewDocWithFile(path);
  var newLayer = app.activeDocument.activeLayer;
  newLayer.name = photoTitle;
  newLayer.isBackgroundLayer = false;
};

var insertImageToActiveDoc = function(path, shouldClip, photoTitle) {
  var activeDoc = app.activeDocument;
  var activeLayer = activeDoc.activeLayer;

  openNewDocWithFile(path);

  var tempDoc = app.activeDocument;
  var tempLayer = tempDoc.activeLayer;
  tempLayer.name = photoTitle;
  tempLayer.isBackgroundLayer = false;

  if (shouldClip) {
    resizeImageToLayerWidth(tempLayer, activeLayer);
  } else {
    resizeToDocWidth(tempLayer, activeDoc);
  }

  positionLayer(tempLayer, 0, 0);

  duplicateToDoc(activeDoc.name); // copy image from tempDoc to the doc

  tempDoc.close(SaveOptions.DONOTSAVECHANGES);
  return activeDoc.activeLayer;
};

var centerImageInLayer = function(imageLayer, layer) {
  var originalRulerUnits = app.preferences.rulerUnits;
  app.preferences.rulerUnits = Units.PIXELS;

  var imageLayerBounds = getBounds(imageLayer);
  var layerBounds = getBounds(layer);
  imageLayer.translate(layerBounds.centerX - imageLayerBounds.centerX, layerBounds.centerY - imageLayerBounds.centerY);

  app.preferences.rulerUnits = originalRulerUnits;
};

var resizeToDocWidth = function(layer, doc) {
  var originalRulerUnits = app.preferences.rulerUnits;
  app.preferences.rulerUnits = Units.PIXELS;

  var layerBounds = getBounds(layer);
  var resizePercentages = (doc.width.as('px') / layerBounds.width) * 100;

  // don't resize if layer is smaller than doc
  if (resizePercentages >= 100) {
    return;
  }

  app.preferences.rulerUnits = Units.PERCENT;
  layer.resize(resizePercentages, resizePercentages, AnchorPosition.MIDDLECENTER);

  app.preferences.rulerUnits = originalRulerUnits;
};

var positionLayer = function(layer, x, y){
  if (layer.isBackgroundLayer || layer.positionLocked) {
    return;
  }

  var originalRulerUnits = app.preferences.rulerUnits;
  app.preferences.rulerUnits = Units.PIXELS;

  var layerBounds = getBounds(layer);
  var layerX = layerBounds.x;
  var layerY = layerBounds.y;
  // difference between where the layer needs to be and it's now
  var deltaX = x - layerX;
  var deltaY = y - layerY;
  // move the layer into position
  layer.translate(deltaX, deltaY);

  app.preferences.rulerUnits = originalRulerUnits;
};

var resizeImageToLayerWidth = function(imageLayer, layer) {
  var originalRulerUnits = app.preferences.rulerUnits;
  app.preferences.rulerUnits = Units.PIXELS;

  var imageLayerBounds = getBounds(imageLayer);
  var layerBounds = getBounds(layer);

  if (layerBounds.width / layerBounds.height > imageLayerBounds.width / imageLayerBounds.height) {
    var resizePercentages = (layerBounds.width / imageLayerBounds.width) * 100;
  } else {
    var resizePercentages = (layerBounds.height / imageLayerBounds.height) * 100;
  }
  resizePercentages = Math.ceil(resizePercentages);

  app.preferences.rulerUnits = Units.PERCENT;
  imageLayer.resize(resizePercentages, resizePercentages, AnchorPosition.MIDDLECENTER);

  app.preferences.rulerUnits = originalRulerUnits;
};

var createClippingMask = function() {
  var actionRef = new ActionReference();
  actionRef.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
  var clippingAction = new ActionDescriptor();
  clippingAction.putReference(charIDToTypeID('null'), actionRef);
  executeAction(charIDToTypeID('GrpL'), clippingAction, DialogModes.NO);
};

var getBounds = function(layer) {
  var layerBounds = layer.bounds;
  var bounds = {};
  bounds.x = layerBounds[0].as('px');
  bounds.y = layerBounds[1].as('px');
  bounds.width = layerBounds[2].as('px') - bounds.x;
  bounds.height = layerBounds[3].as('px') - bounds.y;
  bounds.centerX = bounds.x + (bounds.width / 2);
  bounds.centerY = bounds.y + (bounds.height / 2);
  return bounds;
};

var openNewDocWithFile = function(path) {
  var idnull = charIDToTypeID("null");
    var idOpn = charIDToTypeID("Opn ");
    var desc1 = new ActionDescriptor();
    desc1.putPath(idnull, new File(path));
    desc1.putBoolean(stringIDToTypeID("smartObject"), true);
    executeAction(idOpn, desc1, DialogModes.NO);
};

var duplicateToDoc = function(docName) {
  var idDplc = charIDToTypeID("Dplc");
  var idnull = charIDToTypeID("null");
  var desc1 = new ActionDescriptor();
  var ref1 = new ActionReference();
  var idLyr = charIDToTypeID("Lyr ");
  var idOrdn = charIDToTypeID("Ordn");
  var idTrgt = charIDToTypeID("Trgt");
  ref1.putEnumerated(idLyr, idOrdn, idTrgt);
  desc1.putReference(idnull, ref1);
  var idT = charIDToTypeID("T   ");
  var ref2 = new ActionReference();
  var idDcmn = charIDToTypeID("Dcmn");
  ref2.putName(idDcmn, docName);
  desc1.putReference(idT, ref2);
  var idVrsn = charIDToTypeID("Vrsn");
  desc1.putInteger(idVrsn, 5);
  executeAction(idDplc, desc1, DialogModes.NO);
};
