﻿var CODE_SNIPPETS_URI = fl.applicationURI + fl.languageCode + "/Configuration/CodeSnippets/";


// Used to map player version strings to player version numbers.
var PLAYER_VERSIONS = new Array(
								   {versionString:"1", versionNumber:1},
								   {versionString:"2", versionNumber:2},
								   {versionString:"3", versionNumber:3},
								   {versionString:"4", versionNumber:4},
								   {versionString:"5", versionNumber:5},
								   {versionString:"6", versionNumber:6},
								   {versionString:"7", versionNumber:7},
								   {versionString:"8", versionNumber:8},
								   {versionString:"9", versionNumber:9},
								   {versionString:"FlashPlayer10", versionNumber:10},
								   {versionString:"FlashPlayer10_1", versionNumber:10},
								   {versionString:"AdobeAIR1_5", versionNumber:10},
								   {versionString:"FlashLite", versionNumber:4},
								   {versionString:"FlashLite11", versionNumber:4},
								   {versionString:"FlashLite20", versionNumber:7},
								   {versionString:"FlashLite21", versionNumber:7},
								   {versionString:"FlashLite30", versionNumber:8},
								   {versionString:"FlashLite31", versionNumber:8},
								   {versionString:"FlashLite40", versionNumber:10}
								   );


// Increments all placeholder variables and functions with a counter
// if the snippet is being added two or more times
function autoIncrementIdentifiers(stringToReplace, snippetName)
{
	var str = unescape(stringToReplace);
//	var str = stringToReplace;
	var patt1 = /(fl_(\w)*)/gm;
	var doc = fl.getDocumentDOM();
	
	var counter = doc.getDataFromDocument(snippetName);
	if(counter == 0)
	{
		// if snippet has not been added for this document, don't append a counter
		counter = 2;
		doc.addDataToDocument(snippetName, "integer", counter);
		return str;
	}
	else
	{
		// if snippet has been added for this document, append a counter
		var updatedString = str.replace(patt1, "$1_"+counter);
		counter++;
		doc.addDataToDocument(snippetName, "integer", counter);
		return updatedString;
	}
}


// Returns the index of the first "Actions" layer in the timeline.
// If none of the layers are named "Actions", creates an Actions layer
// at the top layer and returns 0 for the first index.
function getActionsLayerIndex()
{
	var doc = fl.getDocumentDOM()
	var tl = doc.getTimeline();
	var actions_str = "Actions";
	
	var currentLayers = tl.layers;
	var numLayers = currentLayers.length;

	for (var i=0; i<numLayers; i++)
	{
		var curLayer = currentLayers[i];
		if(curLayer.name.toLowerCase() == actions_str.toLowerCase())
		{
			actionsLayerExists = true;
			tl.setSelectedLayers(i);
			return i;
		}
	}

	// if none of the layers is an Actions layer, create one
	tl.currentLayer = 0;
	tl.addNewLayer("Actions");
	tl.setSelectedLayers(0);
	return 0;
}

// Only add actions for movie clip timelines
function isMovieClip()
{
	var item = fl.getDocumentDOM().getTimeline().libraryItem;
	// libraryItem is null for the main Timeline
	if (item)
	{
		if(item.symbolType != "movie clip")
		{
			return "false";
		}
	}

	// return true for main timeline and for movie clips
	return "true";
}

function addSnippetToFrame(xmlNode, noSelectionStr, notASymbolStr, noInstanceNameStr, invokeTimelineHud)
{
	fl.cancelCodeSnippetHUD();

	var codeSnippetXML = XML(unescape(xmlNode));
	
	var s = unescape(codeSnippetXML.code);
	var requiresSymbol = unescape(codeSnippetXML.requiresSymbol);
	var snippetName = unescape(codeSnippetXML.title);

	var doc = fl.getDocumentDOM();
	var tl = doc.getTimeline();

	// if the Code Snippet HUD pushed back an user-entered instance name, and the stars align, set that name on the selected object
	var pushedName = codeSnippetXML.@pushInstanceName;
	if (pushedName != null && doc.selection.length == 1 && doc.selection[0].name == "")
		doc.selection[0].name = pushedName;

	var currentInstanceName = false;
	if(requiresSymbol == "true")
	{
		currentInstanceName = checkSymbol(unescape(noSelectionStr), unescape(notASymbolStr), unescape(noInstanceNameStr));
		if(currentInstanceName == false)
			return;
		else
			currentInstanceName = unescape(currentInstanceName);
	}
	
	var actionsLayerIndex = getActionsLayerIndex();
	
	var cFrame = tl.currentFrame;
	var fCount = tl.layers[actionsLayerIndex].frameCount;
	
	if(cFrame < fCount)
	{
		var sFrame = tl.layers[actionsLayerIndex].frames[cFrame].startFrame;
		if(cFrame != sFrame)
		{
			tl.currentLayer = actionsLayerIndex;
			tl.insertKeyframe(cFrame);
		}
	}
	else
	{
		tl.currentLayer = actionsLayerIndex;
		tl.insertKeyframe(cFrame);	
	}
	
	tl.currentLayer = actionsLayerIndex;
	tl.setSelectedFrames(cFrame, cFrame+1);
	doc.selectNone();
	
	// Bring FLA to front
	fl.setActiveWindow(doc);
	if (invokeTimelineHud == "false")
		fl.showActionsPanel(true);
	
	// replace all occurrences of instance_name_here with the selected instance's name.
	var patt1 = /instance_name_here/gm;
	
	// We replace instance_name_here with the instance name of the selected symbol.
	// Sometimes, a snippet will specify requiredSymbol="false", but still use instance_name_here.
	// In that case, we don't want to replace instance_name_here.
	var codeToInsertReplaced = s;
	if(requiresSymbol != "false")
	{
		codeToInsertReplaced = s.replace(patt1, currentInstanceName);
	}
		
	var updatedCode = autoIncrementIdentifiers(escape(codeToInsertReplaced), snippetName);

	var currentCodeInPanel = tl.layers[actionsLayerIndex].frames[cFrame].actionScript;	
	var beforeAddingSnippetLen = currentCodeInPanel.length;
	var currentText = fl.actionsPanel.getText(true);
	if(currentText != null)
	{
		beforeAddingSnippetLen = currentText.length;
	}
	
	tl.layers[actionsLayerIndex].frames[cFrame].actionScript += updatedCode;
	var afterAddingSnippetLen = tl.layers[actionsLayerIndex].frames[cFrame].actionScript.length;
		
	// Then select the newly added code.
	currentText = fl.actionsPanel.getText(true);
	if(currentText != null)
	{
		afterAddingSnippetLen = currentText.length;
	}
	
	if (invokeTimelineHud == "true") {
		fl.invokeSnippetInsertedHUD(cFrame, beforeAddingSnippetLen, afterAddingSnippetLen);
		return;
	}
	
	// Scroll to the end first to workaround an issue where the Actions Panel only scrolls 
	// to the first line of the newly inserted code.
	fl.actionsPanel.setSelection(afterAddingSnippetLen, 0);
	fl.actionsPanel.setSelection(beforeAddingSnippetLen, afterAddingSnippetLen-beforeAddingSnippetLen);
}

function selectCodeSnippetFromExternalHUD(beforeAddingSnippetLen, afterAddingSnippetLen) {
	fl.showActionsPanel(true);

	// Scroll to the end first to workaround an issue where the Actions Panel only scrolls 
	// to the first line of the newly inserted code.
	fl.actionsPanel.setSelection(Number(afterAddingSnippetLen), 0);
	fl.actionsPanel.setSelection(Number(beforeAddingSnippetLen), Number(afterAddingSnippetLen)-Number(beforeAddingSnippetLen));
}

function checkPickwhipSymbol(noInstanceNameStr) {
	var doc = fl.getDocumentDOM();
	
	if (doc == null)
		return false;
		
	if (doc.getLastPickwhipSelection() == null)
		return false;
	
	var isTextField = false;
	var isButton = false;

	var selectedObj = doc.getLastPickwhipSelection();
	
	if (selectedObj.elementType == "instance") 
	{
		if (selectedObj.instanceType == "symbol") 
		{
			if (selectedObj.symbolType == "button")
			{
				isButton = true;
			}
		}
	}
	else if(selectedObj.elementType == "text")
	{
		isTextField = true;
	}
	else if(selectedObj.elementType == "tlfText")
	{
		isTextField = true;
	}
	
	var retVal;
	if(isTextField)
	{
		retVal = setInstanceName("textField_", unescape(noInstanceNameStr), selectedObj);
	}
	else if(isButton)
	{
		retVal = setInstanceName("button_", unescape(noInstanceNameStr), selectedObj)
	}
	else
	{
		retVal = setInstanceName("movieClip_", unescape(noInstanceNameStr), selectedObj)
	}	
	
	if (false == retVal)
		retVal = null;
		
	return retVal;
}


// Allow movie clip, button, compiled clip, dynamic text, input text.
// All other selections will be converted to a MovieClip.
function checkSymbol(noSelectionStr, notASymbolStr, noInstanceNameStr)
{
	var doc = fl.getDocumentDOM();
	var alreadyActionSymbol = false;
	
	var isTextField = false;
	var isButton = false;
	
	if (doc.selection.length == 0)
	{
		//alert("This action requires an object to be selected on Stage.");
		alert(noSelectionStr);
		return false;
	}

	else if (doc.selection.length == 1) 
	{
		var selectedObj = doc.selection[0];
		if (selectedObj.elementType == "instance") 
		{
			if (selectedObj.instanceType == "symbol") 
			{
				if (selectedObj.symbolType == "movie clip")
				{
					alreadyActionSymbol = true;
				}
				else if (selectedObj.symbolType == "button")
				{
					alreadyActionSymbol = true;
					isButton = true;
				}
			}
			else if (selectedObj.instanceType == "compiled clip") 
			{
				alreadyActionSymbol = true;
			}
		}
		else if(selectedObj.elementType == "text")
		{
			isTextField = true;
			if ((selectedObj.textType == "dynamic") || (selectedObj.textType == "input"))
			{
				alreadyActionSymbol = true;
			}
		}
		else if(selectedObj.elementType == "tlfText")
		{
			isTextField = true;
			alreadyActionSymbol = true;
		}
		
		
		if (!alreadyActionSymbol)
		{
			return convertToSymbol(notASymbolStr);
		}
		else
		{
			if(doc.selection[0].name == "")
			{
				if(isTextField)
				{
					return setInstanceName("textField_", noInstanceNameStr, doc.selection[0]);
				}
				else if(isButton)
				{
					return setInstanceName("button_", noInstanceNameStr, doc.selection[0]);
				}
				else
				{
					return setInstanceName("movieClip_", noInstanceNameStr, doc.selection[0]);
				}
			}
		}
	}

	else
	{
		return convertToSymbol(notASymbolStr);	
	}
			
	var instanceName = doc.selection[0].name;
	return instanceName;
}

function isReservedWord(inWord)
{
	var reservedWords = ["package", "class", "function", "interface", "break", "case", "continue",
		"default", "do", "while", "else", "for", "in", "each", "if", "return", "super", "switch",
		"throw", "try", "catch", "finally", "with", "dynamic", "final", "internal", "native",
		"override", "private", "protected", "public", "static", "const", "extends", "get",
		"implements", "namespace", "set", "var", "import", "include", "use", 
		"false", "true", "this", "null"];
	for each(var aWord in reservedWords)
		if (aWord == inWord)
			return true;
	return false;
}

function getSnippetHUDInstanceNameText() {
	if (fl.documents.length)
	{
		var doc = fl.getDocumentDOM();
		if (doc != null & doc.selection.length == 1) 
		{
			var selectedObj = doc.selection[0];
			var canUseSelectedInstance = false;
			if (selectedObj.elementType == "instance")
			{
				if (selectedObj.instanceType == "symbol")
				{
					if (selectedObj.symbolType == "movie clip")
						canUseSelectedInstance = true;
					else if (selectedObj.symbolType == "button")
						canUseSelectedInstance = true;
				}
				else if (selectedObj.instanceType == "compiled clip")
					canUseSelectedInstance = true;
			}
			else if(selectedObj.elementType == "text")
			{
				if ((selectedObj.textType == "dynamic") || (selectedObj.textType == "input"))
					canUseSelectedInstance = true;
			}
			else if(selectedObj.elementType == "tlfText")
				canUseSelectedInstance = true;
			if (canUseSelectedInstance)
				return selectedObj.name;	// OK if it's an empty string, enables name pushing workflow
		}
    }
    return "instance_name_here";	// This value means don't change instance name in snippet.
}

function setInstanceName(namePrefix, noInstanceNameStr, instanceToName)
{
	var doc = fl.getDocumentDOM();
	var counter = fl.getDocumentDOM().getDataFromDocument("snippetCounter");
	if(counter == 0)
	{
		counter = 1;
	}		
	var instanceName = namePrefix + counter++;
 	var hideNoInstanceNameDialog = fl.getPrefInteger("Warning_Dialog_Windows", "Snippets_NoInstanceName");
 	if (hideNoInstanceNameDialog == 0)
 	{
		doc.addDataToDocument("defaultNewInstanceName", "string", instanceName);
		var validName = false;
		do {
			var xulResult = fl.xmlPanel(CODE_SNIPPETS_URI + 'SetInstanceName.xml');
			if (xulResult.dismiss == "cancel")
				return false;
			if (!fl.isValidIdentifier(xulResult.instanceName) || isReservedWord(xulResult.instanceName))
			{
				alert(noInstanceNameStr.replace("{instanceName}", xulResult.instanceName));
				doc.addDataToDocument("defaultNewInstanceName", "string", xulResult.instanceName);
			}
			else
				validName = true;
		} while (!validName)
		var newInstanceName = instanceToName.name = xulResult.instanceName;
		if (xulResult.dontShowAgain == "true")
			fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_NoInstanceName", 1);
		if (newInstanceName == instanceName)
			doc.addDataToDocument("snippetCounter", "integer", counter);
		return escape(newInstanceName);
	}
	else
	{
		instanceToName.name = instanceName;
		doc.addDataToDocument("snippetCounter", "integer", counter);
		return instanceName;
	}
}

function convertToSymbol(notASymbolStr)
{
	var doc = fl.getDocumentDOM();
		
	var hideNotASymbolDialog = fl.getPrefInteger("Warning_Dialog_Windows", "Snippets_NotASymbol");
	if(hideNotASymbolDialog == 0)
	{
		var notASymbolArr = confirmWithOption(notASymbolStr);
				
		if(!notASymbolArr[0])
		{
			return false;
		}
		
		if(notASymbolArr[1])
		{
			fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_NotASymbol", 1);
		}
	}
	
	doc.convertToSymbol("movie clip", "" , "center");
	var counter = fl.getDocumentDOM().getDataFromDocument("snippetCounter");
	if(counter == 0)
	{
		counter = 1;
	}		
	var instanceName = doc.selection[0].name = "movieClip_" + counter++;
	doc.addDataToDocument("snippetCounter", "integer", counter);
	return instanceName;
}

function resetWarnings()
{
	fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_NotASymbol", 0);
	fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_NoInstanceName", 0);
//	fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_Success", 0);
	fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_CCSuccess", 0);
}

function revertXML(confirmDeleteStr)
{
//	var originalFileURI = fl.configURI + "WindowSWF/CustomizePanel_default.xml";
	var originalFileURI = fl.applicationURI + fl.languageCode + "/First%20Run/CodeSnippets/CodeSnippets.xml";
//	var fileURI = fl.configURI + "WindowSWF/CustomizePanel.xml";
	var fileURI = fl.configURI + "CodeSnippets/CodeSnippets.xml";
	var doDelete = confirm(unescape(confirmDeleteStr));
	if(doDelete)
	{
		FLfile.remove(fileURI);
		FLfile.copy(originalFileURI, fileURI);
		return "true";	
	}
	else
	{
		return "false";
	}
}

function showCCSuccessDialog()
{
//	var doc = fl.getDocumentDOM();
		
	var hideCCSuccessDialog = fl.getPrefInteger("Warning_Dialog_Windows", "Snippets_CCSuccess");
	if(hideCCSuccessDialog == 0)
	{
//		var xulResult = doc.xmlPanel(fl.configURI + "WindowSWF/XULFiles/SuccessCopyClipboard.xml");
		var xulResult = fl.xmlPanel(CODE_SNIPPETS_URI + 'SuccessCopyClipboard.xml');
						
		if(xulResult.disableWarning_ch == "true")
		{
			fl.setPrefInteger("Warning_Dialog_Windows", "Snippets_CCSuccess", 1);
		}
	}
}

function createNewSnippet()
{
//	var doc = fl.getDocumentDOM();
		
	var xulResult = fl.xmlPanel(CODE_SNIPPETS_URI + 'CreateNewSnippet.xml');
						
	if(xulResult.dismiss == "cancel")
	{
		return false;
	}
	else
	{
		var arr = new Array();
		arr[0] = escape(xulResult.Title);
		arr[1] = escape(xulResult.Tooltip);
		arr[2] = escape(xulResult.Code);
		arr[3] = escape(xulResult.requiresSymbol_ch);
		
		return arr;
	}
}

function importSnippet(selectXMLStr)
{
	var macFormat = "XML|XML[*.xml||";
	var winFormat = "XML|*.xml||";
	
	//Third parameter is for Dreamweaver only
	var xmlToImport = fl.browseForFileURL("open", unescape(selectXMLStr), {}, macFormat, winFormat);

	if(xmlToImport == null)
	{
		return "false";
	}
	else
	{
		var xmlToImportStr = FLfile.read(xmlToImport);
		return escape(xmlToImportStr);
	}
}

function exportSnippet(exportXMLStr)
{
	var macFormat = "XML|XML[*.xml||";
	var winFormat = "XML|*.xml||";
	
	//Third parameter is for Dreamweaver only
	var exportTargetURI = fl.browseForFileURL("save", unescape(exportXMLStr), {}, macFormat, winFormat);

	var fileURI = fl.configURI + "CodeSnippets/CodeSnippets.xml";

	if(exportTargetURI == null)
	{
		return;
	}
	
	var exportSucceeded = false;
	if(isExtension(exportTargetURI, ".xml"))
	{
		exportSucceeded = FLfile.copy(fileURI, exportTargetURI);
	}
	else
	{
		exportSucceeded = FLfile.copy(fileURI, exportTargetURI + ".xml");
	}
	
	if(!exportSucceeded)
	{
		return "false";
	}
}

// Helper function to verify export file URI has .xml extension
function isExtension(str, ext)
{
	var str2 = str.substr(str.length-4);
	return (str2.toLowerCase() == ext.toLowerCase());
}


   
// Helper function that returns the player's major version as a number
// based on the document's player version as a string.
function getPlayerVersionNumber(playerString)
{
	var len = PLAYER_VERSIONS.length;
	for(var i=0; i < len; i++)
	{
		var pItem = PLAYER_VERSIONS[i];
		if(playerString == pItem.versionString)
		{
			return pItem.versionNumber;
		}
	}
	return -1;
}


// Restrict snippets by Player and ActionScript version restriction
// Currently, doesn't support AIR version restriction.
function checkVersions(xmlNode, versionWarningString)
{
	var doc = fl.getDocumentDOM();
	var docASVersion = doc.asVersion;	
	var docPlayerVersion = getPlayerVersionNumber(doc.getPlayerVersion());

	var codeSnippetXML = XML(unescape(xmlNode));
	
	var minASVersion = Number(codeSnippetXML.minASVersion);
	var maxASVersion = Number(codeSnippetXML.maxASVersion);
	
	var minPlayerVersion = Number(codeSnippetXML.minPlayerVersion);
	var maxPlayerVersion = Number(codeSnippetXML.maxPlayerVersion);
	
	var isASValid = false;
	var isPlayerValid = false;

	if( (minASVersion == 0) && (maxASVersion == 0) )
	{
		isASValid = true;
	}
	else if ( (minASVersion != 0) && (maxASVersion != 0) && (minASVersion <= docASVersion) && (docASVersion <= maxASVersion) )
	{
		isASValid = true;
	}
	else if ( (minASVersion != 0) && (minASVersion <= docASVersion) && (docASVersion <= maxASVersion) )
	{
		isASValid = true;
	}
	else if ( (maxASVersion != 0) && (docASVersion <= maxASVersion) && (minASVersion <= docASVersion) )
	{
		isASValid = true;
	}
	else if ( (maxASVersion == 0) && (minASVersion <= docASVersion) )
	{
		isASValid = true;
	}
	
	

	if( (minPlayerVersion == 0) && (maxPlayerVersion == 0) )
	{
		isPlayerValid = true;
	}
	else if ( (minPlayerVersion != 0) && (maxPlayerVersion != 0) && (minPlayerVersion <= docPlayerVersion) && (docPlayerVersion <= maxPlayerVersion) )
	{
		isPlayerValid = true;
	}
	else if ( (minPlayerVersion != 0) && (minPlayerVersion <= docPlayerVersion) && (docPlayerVersion <= maxPlayerVersion) )
	{
		isPlayerValid = true;
	}
	else if ( (maxPlayerVersion != 0) && (docPlayerVersion <= maxPlayerVersion) && (minPlayerVersion <= docPlayerVersion) )
	{
		isPlayerValid = true;
	}
	else if ( (maxPlayerVersion == 0) && (minPlayerVersion <= docPlayerVersion) )
	{
		isPlayerValid = true;
	}
	

	if(isASValid && isPlayerValid)
	{
		return "true";
	}
	else
	{
		if( (minASVersion == 0) && (maxASVersion == 1) )
		{
			// Need to special case where minASVersion is 0 and maxASVersion is 1.  Otherwise, the player warning
			// dialog shows ActionScript 1.0 - ActionScript 1.0.
			fl.showPlayerWarningDialog((minPlayerVersion == 0) ? 1 : minPlayerVersion, maxPlayerVersion, isPlayerValid, maxASVersion, minASVersion, isASValid, unescape(versionWarningString));
		}
		else
		{
			fl.showPlayerWarningDialog((minPlayerVersion == 0) ? 1 : minPlayerVersion, maxPlayerVersion, isPlayerValid, (minASVersion == 0) ? 1 : minASVersion, maxASVersion, isASValid, unescape(versionWarningString));
		}
		return "false";
	}

}
