﻿// rd_BatchVectorToShape.jsx
// Copyright (c) 2012-2013 redefinery (Jeffrey R. Almasol). All rights reserved.
// check it: www.redefinery.com
// 
// Name: rd_BatchVectorToShape
// Version: 1.1
// 
// Description:
// This script batch converts the selected vector layers to 
// shape layers. It'll skip any selected layers that can't be 
// converted. Each converted shape layer is positioned
// immediately above the original vector layer (unlike the
// Create Shapes from Vector Layer menu command's
// default behavior).
// 	
// Note: This version of the script requires After Effects CS6 
// or later. English version only at this time.cd 
// 
// Originally requested by Kevin Snyder.
// 
// Legal stuff:
// This script is provided "as is," without warranty of any kind, expressed
// or implied. In no event shall the author be held liable for any damages
// arising in any way from the use of this script.
// 
// In other words, I'm just trying to share knowledge with and help out my
// fellow AE script heads, so don't blame me if my code doesn't rate. :-)




// rd_BatchVectorToShape()
// 
// Description:
// This function contains the main logic for this script.
// 
// Parameters:
// thisObj - "this" object.
// 
// Returns:
// Nothing.
//
(function rd_BatchVectorToShape(thisObj)
{
	// Globals

	var rd_BatchVectorToShapeData = new Object();	// Store globals in an object
	rd_BatchVectorToShapeData.scriptName = "rd: Batch Vector to Shape";
	rd_BatchVectorToShapeData.scriptTitle = rd_BatchVectorToShapeData.scriptName + " v1.0";

	rd_BatchVectorToShapeData.lang = app.isoLanguage.split("_")[0];
	rd_BatchVectorToShapeData.menuCommand = {
		en: "Create Shapes from Vector Layer",
		de: "Formen aus Vektorebene erstellen",
		fr: "Créer des formes à partir du calque vectoriel",
		it: "Crea forme da livello vettoriale",
		es: "Creación de formas a partir de la capa vectorial",
		ja: "ベクトルレイヤーからシェイプを作成",
		ko: "벡터 레이어에서 모양 만들기",
		zh: "从矢量图层创建形状"
	};

	rd_BatchVectorToShapeData.strHelp = {en: "?"};
	rd_BatchVectorToShapeData.strNoCompSel = {en: "Select or open a composition, then try again."};
	rd_BatchVectorToShapeData.strNoLayerSel = {en: "Select at least one vector layer, then try again."};
	rd_BatchVectorToShapeData.strMinAE110 = {en: "This script requires Adobe After Effects CS6 or later."};
	rd_BatchVectorToShapeData.strHelpText = 
	{
		en: "Copyright (c) 2012-2013 redefinery (Jeffrey R. Almasol).\n" +
		"All rights reserved.\n" +
		"\n" +
		"This script batch converts the selected vector layers to shape layers. It'll skip any selected layers that can't be converted. Each converted shape layer is positioned immediately above the original vector layer (unlike the Create Shapes from Vector Layer menu command's default behavior).\n" +
		"\n" +
		"Note: This version of the script requires After Effects CS6 or later. English version only at this time.\n" +
		"\n" +
		"Originally requested by Kevin Snyder."
	};




	// rd_BatchVectorToShape_localize()
	// 
	// Description:
	// This function localizes the given string variable based on the current locale.
	// 
	// Parameters:
	//   strVar - The string variable's name.
	// 
	// Returns:
	// String.
	//
	function rd_BatchVectorToShape_localize(strVar)
	{
		var value = strVar[rd_BatchVectorToShapeData.lang];
		if (value == undefined)
			value = strVar["en"];
		
		return value;
	}




	// rd_BatchVectorToShape_doIt()
	// 
	// Description:
	// This callback function performs the main operation.
	// 
	// Parameters:
	// None.
	// 
	// Returns:
	// Nothing.
	//
	function rd_BatchVectorToShape_doIt()
	{
		var comp = app.project.activeItem;
		if ((comp === null) || !(comp instanceof CompItem)) {
			alert(rd_BatchVectorToShape_localize(rd_BatchVectorToShapeData.strNoCompSel));
			return;
		}
		if (comp.selectedLayers.length === 0) {
			alert(rd_BatchVectorToShape_localize(rd_BatchVectorToShapeData.strNoLayerSel));
			return;
		}
		comp.openInViewer();	// just to make sure the comp's panel is frontmost

		// make a copy of the selected vector layers, in reverse layer order
		var selLayers = new Array();
		for (var i=comp.numLayers; i>0; i--) {
			if (comp.layer(i).selected && (comp.layer(i) instanceof AVLayer)) {
				selLayers[selLayers.length] = comp.layer(i);
				selLayers[selLayers.length-1].selected = false;	// deselect layers as we process them
			}
		}

		app.beginUndoGroup(rd_BatchVectorToShapeData.scriptName);

		// loop through the previously selected vector layers
		var numLayersInComp = comp.numLayers;	// keep track of the original number of layers (so we know if any shape layer was actually created)
		for (var i=0; i<selLayers.length; i++) {
			var l = selLayers[i];	// select each layer to process
			l.selected = true;
			try {
				// invoke the menu command
				app.executeCommand(3973);	// Create Shapes from Vector Layer  // app.findMenuCommandId(rd_BatchVectorToShape_localize(rd_BatchVectorToShapeData.menuCommand)));

				// spot-check if the command actually worked (i.e., created a new, shape layer).
				// this check is needed in case the command failed (failed to convert, or not a vector layer)
				if (comp.numLayers !== (numLayersInComp+1)) {
					l.selected = false;
					continue;
				}

				// converted shape layer is at the top of the comp, so move it just above the original vector layer
				var lv = comp.layer(1);
				lv.moveBefore(l);
				lv.selected = false;

				numLayersInComp++;	// increment the number of layers now in the comp
			}
			catch (e)
			{}
		}

		app.endUndoGroup();
	}




	// main code:
	//

	// Prerequisites check
	if (parseFloat(app.version) < 11.0)
		alert(rd_BatchVectorToShape_localize(rd_BatchVectorToShapeData.strMinAE110), rd_BatchVectorToShapeData.scriptName);
	else
		rd_BatchVectorToShape_doIt();
})(this);
