
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2008 Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
* $DateTime: 2008/04/10 13:35:00 $
*
* Adobe Output Module 2.0
*
* MediaGallery Originally Written by Quality Process Incorporated, Enhanced by
* Adobe System China. Contact Sheet written by Adobe System China.
* 
*
**************************************************************************/


AOM.ZStringGalleryCreatorTitle = AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/CreateGallery=Create Gallery");
AOM.ZStringGalleryCreatorSkipping = AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Skipping= - Skipping...");
AOM.ZStringGalleryCreatorUsingFullBitmap = AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/UseFullBitmap= - Using full bitmap...");



AOM.AmgGalleryCreator = function(galleryType, formData, images)
{
	this.galleryType = galleryType;
	this.images = images;
	this.imageCount = 0;
	this.formData = formData;
	this.destinationFolder = "";
	this.webAccessLib = undefined;
	this.ftp = undefined;
	var userInput = AOM.AMG.userInput(formData.document);
	this.template = userInput.get("t_template");
	this.jpegQuality = Number(userInput.get("jpegQualitySlider"));
	var taskManagerName = "createGallery" + formData.documentID;
	var oldTaskManager = AOM.TaskManager.find(taskManagerName);
	if(oldTaskManager != undefined && (oldTaskManager.state == "running" || oldTaskManager.state == "paused")) {
		this.taskManager = undefined;
		return;
	}
	this.taskManager = new AOM.TaskManager(taskManagerName, AOM.ZStringGalleryCreatorTitle);
}
AOM.AmgGalleryCreator.createModes =
{
	preview			: { value : 0, description : "preview" },
	saveToDisk		: { value : 1, description : "save to disk" },
	upload			: { value : 2, description : "upload" },
	previewInBrowser: {	value : 3, description : "preview in browser"},
};
AOM.AmgGalleryCreator.galleryTypes =
{
	flash	: { value : 0, description : "flash" },
	html 	: { value : 1, description : "html" },
	airtight: { value : 2, description : "airtight" }
};
AOM.AmgGalleryCreator.errors =
{
	abort	: { value : 0, description : "abort" },
	cancel	: { value : 1, description : "cancel" }
};
AOM.AmgGalleryCreator.prototype.create = function()
{
	try
	{
		var that = this;
		var ftpCancel = function() { if (that.ftp != undefined) that.ftp.close(); }
		this.taskManager.configureCancel({action:ftpCancel, button:AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Cancel=Cancel")});
		this.taskManager.startGroup(AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Initializing=Initializing"), 3);
		this.imageCount = AOM.AmgGalleryCreator.imagePrep(this.images);
		if (this.imageCount == 0)
		{
			this.taskManager.stop({title: AOM.ZStringGalleryCreatorTitle,
                                   description: AOM.localize("$$$/MediaGallery/Javascript/WebGallery/Processed=Web Gallery Processed."),
                                   detail: AOM.AMG.localize("$$$/ContactSheet/javascript/pdfGenerator/selectAllNoneImageFile=None of the selected files are supported image files.")});
			return false;
		}
		var func = function () {that.preGalleryCreationTests();}
		var func2 = function () {that.createModeConfiguration();}
		var func3 = function () {that.ftpInit();}
		this.taskManager.addTask(func, AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Tests=Gallery creation tests..."));
		this.taskManager.addTask(func2, AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/ModeConfiguration=Create mode configuration..."));
		this.taskManager.addTask(func3, AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/FTPInit=FTP initialization..."));

		switch (this.galleryType)
		{
		 case AOM.AmgGalleryCreator.galleryTypes.flash:
		 	var func4 = function () {
					AOM.AmgFlashGalleryCreator(that.images, that.destinationFolder,
											   that.taskManager, that.formData.document,
											   that.formData.createMode, that.jpegQuality);
            }
			this.taskManager.addTask(
				func4, AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/ContentCreation=Gallery content creation..."));
			break;
		 case AOM.AmgGalleryCreator.galleryTypes.html:
		 	var func5 = function () {
				AOM.AmgHtmlGalleryCreator(that.images, that.destinationFolder,
										  that.taskManager, that.formData.document,
										  that.formData.createMode, that.jpegQuality);
            }
			this.taskManager.addTask(func5);
			break;
		case AOM.AmgGalleryCreator.galleryTypes.airtight:
			var viewerMode;
			if (this.template == "09postcardviewer")
				viewerMode = "postcard";
			if (this.template == "10autoviewer")
				viewerMode = "auto";
			if (this.template == "11simpleviewer")
				viewerMode = "simple";
			var func7 = function () {
				AOM.AmgAirtightGalleryCreator(that.images, that.destinationFolder,
										  that.taskManager, that.formData.document,
										  that.formData.createMode, viewerMode, that.jpegQuality);
            }
			this.taskManager.addTask(func7);
			break;
		 default:
			AOM.AMG.Log.writeError("AOM.AmgGalleryCreator.create - unknown gallery type ("+this.galleryType.description+")");
			this.taskManager.stop({
                title: AOM.ZStringGalleryCreatorTitle,
                description: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/UnkownGalleryType=Unknown gallery type."),
                button: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/OK=OK")
            });
			break;
		}

		var detailFunction = function () {return AOM.AmgGalleryCreator.galleryCreatedDetail(that.images);}
		var unPrepFunction = function () 
		{
			AOM.AmgGalleryCreator.unPrepImages(that.images)
			var imageCache = AOM.ImageCache.getInstance();
			if (imageCache != undefined)
				imageCache.update();
		}
		if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.preview) {
			var pStopDetail = function() {
				var invalidImageCount = 0;
				for (var i = 0; i < that.images.length; i++) {
					if (that.images[i].amgSkip()) {
						invalidImageCount++;
					}
				}
				if (invalidImageCount > 0) {
					if (invalidImageCount == that.images.length) {
						return AOM.localize("$$$/ContactSheet/javascript/pdfGenerator/selectAllNoneImageFile=None of the selected files are supported image files.");
 					} else {
						that.formData.previewFunction(new File(that.destinationFolder + "/index.html"));
						return AOM.localize("$$$/ContactSheet/javascript/pdfGenerator/selectSomeNoneImageFile=Some of the selected files are not supported image files.");
					}
				} else {
					that.taskManager.showProgressOnStop = false;
					that.formData.previewFunction(new File(that.destinationFolder + "/index.html"));
				}
			};
		
			this.taskManager.configureOnStop(
				{
					description: AOM.localize("$$$/MediaGallery/Javascript/WebGallery/Processed=Web Gallery Processed."), 
					detail: pStopDetail, 
					action: unPrepFunction,
				}
			);
		} else if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.previewInBrowser) {
			var pbStopDetail = function() {
				var invalidImageCount = 0;
				for (var i = 0; i < that.images.length; i++) {
					if (that.images[i].amgSkip()) {
						invalidImageCount++;
					}
				}
			
				that.executePreviewStatus = -1;
				if (invalidImageCount > 0) {
					if (invalidImageCount == that.images.length) {
						that.executePreviewStatus = 0;
						return AOM.localize("$$$/ContactSheet/javascript/pdfGenerator/selectAllNoneImageFile=None of the selected files are supported image files.");
 					} else {
						that.executePreviewStatus = 1;
						return AOM.localize("$$$/ContactSheet/javascript/pdfGenerator/selectSomeNoneImageFile=Some of the selected files are not supported image files.");
					}
				} else {
					that.taskManager.showProgressOnStop = false;
					that.formData.previewFunction(new File(that.destinationFolder + "/index.html"));
				}
			};
		
			var pbOnStop = function() {
				if (that.executePreviewStatus == 1) {
					that.formData.previewFunction(new File(that.destinationFolder + "/index.html"));
					that.executePreviewStatus = -1;
				}
				//free images
				for (var i = 0; i < that.images.length; i++) {
					that.images[i] = undefined;
				}
			}
		
			this.taskManager.configureOnStop(
				{
					description: AOM.localize("$$$/MediaGallery/Javascript/WebGallery/Processed=Web Gallery Processed."), 
					detail: pbStopDetail, 
					action: pbOnStop,
				}
			);	
		} else {
			var pbStopDetail = function() {
				var invalidImageCount = 0;
				for (var i = 0; i < that.images.length; i++) {
					if (that.images[i].amgSkip()) {
						invalidImageCount++;
					}
				}
			
				if (invalidImageCount > 0) {
					if (invalidImageCount == that.images.length) {
						return AOM.localize("$$$/ContactSheet/javascript/pdfGenerator/selectAllNoneImageFile=None of the selected files are supported image files.");
 					} else {
						return AOM.localize("$$$/ContactSheet/javascript/pdfGenerator/selectSomeNoneImageFile=Some of the selected files are not supported image files.");
					}
				}
			};
			if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.upload)
			{
				this.taskManager.configureOnStop(
					{
						title: AOM.ZStringGalleryCreatorTitle,
						description: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Uploaded=Gallery uploaded."),
						detail: pbStopDetail,
					}
				);
				var func6 = function () {that.ftp.upload();}
				this.taskManager.addTask(func6, AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Uploading=Upload gallery..."));
			}
			else
			{
				this.taskManager.configureOnStop(
					{
						title: AOM.ZStringGalleryCreatorTitle,
						description: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/Created=Gallery created."),
						detail: pbStopDetail,
						action: unPrepFunction
					}
				);
			}
		}
		this.taskManager.start();
		return true;
	}
	catch (e)
	{
		AOM.AMG.Log.writeError("caught - " + e);
		return false;
	}
}
AOM.AmgGalleryCreator.galleryCreatedDetail = function (images)
{
	for (var i = 0; i < images.length; i++)
	{
		if (images[0].amgSkip())
			return AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/ItemsSkipped=One or more seleted items was skipped.");
	}
	return "";
}
AOM.AmgGalleryCreator.unPrepImages = function (images)
{
	for (var i = 0; i < images.length; i++)
	{
		images[i].amg = undefined;
	}
}
AOM.AmgGalleryCreator.prototype.createModeConfiguration = function()
{
	if ((this.formData.createMode == AOM.AmgGalleryCreator.createModes.preview)
		|| this.formData.createMode == AOM.AmgGalleryCreator.createModes.previewInBrowser)
	{
		// limit the number of images for preview
		AOM.AmgGalleryCreator.previewPrep(this.images);
		// indicate that we are creating a preview?
		
		// generate the flash security files
		this.writeFlashPermissionFile();
	}
	
	if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.preview ||
		this.formData.createMode == AOM.AmgGalleryCreator.createModes.previewInBrowser ||
		this.formData.createMode == AOM.AmgGalleryCreator.createModes.upload)
	{
		// for preview and upload write to a temporary directory
        var previewFolder = this.formData.document.id + "/";
        if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.preview)
             previewFolder = AOM.AMG.Paths.preview + previewFolder;
        else
             previewFolder = AOM.AMG.Paths.previewInBrowser + previewFolder;
            
		if(!Folder(previewFolder))
		    Folder(previewFolder).create();
		this.destinationFolder = new Folder(previewFolder);
	}
	
	if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.upload)
	{
	}
	
	if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.saveToDisk)
	{
		// for save to disk write to user specified direcotry
		this.destinationFolder = new Folder(this.formData.saveLocation + "/" + this.formData.galleryName);
	}
	if (this.galleryType == AOM.AmgGalleryCreator.galleryTypes.airtight)
	{
		if (this.images.length > 200)
		{
			var imageCount = 0;
			for (var i = 0; i < this.images.length; i++)
			{
				var image = this.images[i];
				if (image.amgSkip())
					continue;
				imageCount++;
				if (imageCount > 200)
					this.images.length = i; // truncate the array and fall out of loop
			}
			AOM.alert(AOM.localize("$$$/MediaGallery/galleryCreation/sizeLimitation=Only 200 supported pictures in the front can be used in the gallery."));
		}
	}
}

AOM.AmgGalleryCreator.prototype.writeFlashPermissionFile = function ()
{
	var destination = "/Macromedia/Flash Player/#Security/FlashPlayerTrust";
	if (File.fs == "Macintosh")
		destination = "~/Library/Preferences" + destination;
	else
		destination = Folder.userData + destination;
	
	var file = new File(destination+"/AdobeOutputModule3.cfg");
	if (file.exists)
	{
		if (AOM.AMG.verbose) AOM.AMG.Log.writeLine("found a permission file ("+file.fsName+")");
		return;
	}
	var folder = new Folder(destination);
	if (!folder.exists)
	{
		if (!folder.create())
		{
			AOM.AMG.Log.writeError("writeFlashPermissionFile - could not create destination ("+folder.fsName+")");
			throw({action:"stop", title: AOM.ZStringDialogTitle, description:"Could not create Flash permissions folder - gallery creation stopped"});
		}
		else
		{
			if (AOM.AMG.verbose) AOM.AMG.Log.writeLine("created the permission folder ("+folder.fsName+")");
		}
	}
	else
	{
		if (AOM.AMG.verbose) AOM.AMG.Log.writeLine("found the permission folder ("+folder.fsName+")");
	}
		
	file.lineFeed = "unix";
	if (!file.open("w", "TEXT", "????"))
	{
		AOM.AMG.Log.writeError("writeFlashPermissionFile - could not open permissions file ("+file.fsName+")");
		throw({action:"stop", title: AOM.ZStringDialogTitle,
               description: AOM.AMG.localize("$$/MediaGallery/JavaScript/FlashGallery/FailOpenPermissionFile=Could not open permissions file - gallery creation stopped") });
	}

	var folder  = new Folder(AOM.AMG.Paths.user);
    file.write(folder.fsName + "\n");
    
	if (AOM.AMG.verbose) AOM.AMG.Log.writeLine("wrote the permission file ("+file.fsName+")");
	file.close();
}

AOM.AmgGalleryCreator.prototype.ftpInit = function()
{
	if (this.formData.createMode == AOM.AmgGalleryCreator.createModes.upload)
	{
		this.ftp = AOM.AMG.WebAccess.ftp();
		if (this.ftp != undefined)
			this.ftp.open(this.formData.ftpServer, this.formData.userName, this.formData.password, this.destinationFolder, this.formData.uploadFolder+"/"+this.formData.galleryName, this.taskManager);
		else
			AOM.AMG.Log.writeError("AOM.AmgGalleryCreator.ftpInit - could not get ftp");			
	}
}
AOM.AmgGalleryCreator.prototype.preGalleryCreationTests = function()
{
	// do some sanity checks before we start the heavy lifting..
	var error = undefined;
	this.validateGalleryTypeAndFormData();
	switch (this.formData.createMode)
	{
	 case AOM.AmgGalleryCreator.createModes.saveToDisk:
		// check that destinations folders are in order
		// saveLocation should exist
		var folder = new Folder(this.formData.saveLocation);
		if (!folder.exists)
		{
			throw({action:"stop", title: AOM.ZStringGalleryCreatorTitle, description: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/SaveLoactionNotExist=Save location does not exist.")});
		}
		// saveLocation/galleryName should not exist
		folder = new Folder(this.formData.saveLocation + "/" + this.formData.galleryName);
		if (folder.exists)
		{
			var confirmText = AOM.AMG.localize("$$$/MediaGallery/galleryCreation/galleryFolderExistsA=A folder with the Gallery Name");
			confirmText += " '" + File.decode(folder.name);
			confirmText += "' " + AOM.AMG.localize("$$$/MediaGallery/galleryCreation/galleryFolderExistsB=already exists.");
			confirmText += "\n\n" + AOM.AMG.localize("$$$/MediaGallery/galleryCreation/wantToOverwrite=Do you want to overwrite it?");
			if (!AOM.confirm(confirmText))
			{
				// the user would like to try again
				//error = AOM.AmgGalleryCreator.errors.cancel;
				//error.description = "don't overwrite saveLocation";
				throw({action:"cancel"});
			}
			// remove the existing folder
			AOM.AMG.removeFolderContents(folder); // delete the contents of the folder
			folder.remove(); // and delete the folder
		}
		break;
	 // nothing to do for upload or preview?
	 case AOM.AmgGalleryCreator.createModes.upload:
	 case AOM.AmgGalleryCreator.createModes.preview:
	 case AOM.AmgGalleryCreator.createModes.previewInBrowser:
	 default:
		break;
	};
}		
AOM.AmgGalleryCreator.prototype.validateGalleryTypeAndFormData = function()
{
	var error = AOM.AmgGalleryCreator.errors.abort;
	error.description = "GalleryCreator - ";
	
	// quick check that we have a galleryType we like..
	switch (this.galleryType)
	{
	case AOM.AmgGalleryCreator.galleryTypes.flash:
	case AOM.AmgGalleryCreator.galleryTypes.html:
	case AOM.AmgGalleryCreator.galleryTypes.airtight:
		//looks good...
		break;
	default:
		AOM.AMG.Log.writeError("validateGalleryTypeAndFormData - unknown gallery type ("+this.galleryType+")");
		throw({action:"stop", title: AOM.ZStringGalleryCreatorTitle, description: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/UnknownGalleryTypeStop=Unknown gallery type - gallery creation stopped.") });
		break;
	}
	
	// quick check that we have a useable formData object..
	switch (this.formData.createMode)
	{
	case AOM.AmgGalleryCreator.createModes.preview:
	case AOM.AmgGalleryCreator.createModes.previewInBrowser:
	case AOM.AmgGalleryCreator.createModes.saveToDisk:
	case AOM.AmgGalleryCreator.createModes.upload:
		// looks good...
		break;
	default:
		AOM.AMG.Log.writeError("validateGalleryTypeAndFormData - unknown create mode ("+this.formData.createMode+")");
		throw({action:"stop", title: AOM.ZStringGalleryCreatorTitle, description: AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/UnknownCreateMode=Unknown create mode - gallery creation stopped.") });
		break;
	};
}

AOM.AmgGalleryCreator.processImages = function(images, sizesList, imageMaximumDimension, imagesFolder, copyright,
											   taskManager, createMode, onCompletionCallback, jpegQuality)
{
	var imageCache = AOM.ImageCache.getInstance();
	var log = false;
	var testImage = function(image, size)
	{
		if (image.amgSkip()) {
			return true;
		}
		var preserveColorProfile = AOM.BridgePreferences.getPreserveColorProfile();
		preserveColorProfile = (preserveColorProfile == "true");
		
		image.allSizeExist = true;
		image.preserveColorProfile = preserveColorProfile;
		
		var candidateSizes;
		if (size == undefined) {
			image.amg.sizes = {};
			candidateSizes = sizesList;
		} else {
			candidateSizes = new Object();
			candidateSizes[size] = {};
		}

		for (var i in candidateSizes) {
			var size = sizesList[i];

			var demandInfo = {};
			demandInfo.colorProfilePreserved = preserveColorProfile;
			demandInfo.rotateToFit = false;
			demandInfo.height = size.height;
			demandInfo.width = size.width;
			demandInfo.fullResolution = false;
			demandInfo.jpegQuality = jpegQuality;

			image.amg.sizes[i] = {};
			image.amg.sizes[i].size = size.size;
			image.amg.sizes[i].needCreate = false;
			image.amg.sizes[i].demandInfo = demandInfo;

			if ((createMode == AOM.AmgGalleryCreator.createModes.preview)
				|| (createMode == AOM.AmgGalleryCreator.createModes.previewInBrowser))
				var result = imageCache.findDemand(image, demandInfo, 1.1, 20);
			else
				var result = imageCache.findDemand(image, demandInfo, 1, 0);
			
			if (result.originalFileSupported) {
				if(result.cacheImagePath != undefined) {
					var imageFile = new File(result.cacheImagePath);
					if (!imageFile.exists) {
						image.amg.sizes[i].needCreate = true;
						image.allSizeExist = false;
					} else {
						image.amg.sizes[i].width  = result.width;
						image.amg.sizes[i].height = result.height;
						image.amg.sizes[i].cacheImagePath = result.cacheImagePath;
					}
				} else {
					image.amg.sizes[i].needCreate = true;
					image.allSizeExist = false;
				}
			} else {
				image.amgSkip(true);
				image.allSizeExist = true;
				return true;
			}
		}
	}

	var processImage = function (images, startIndex)
	{
		for(var i = startIndex; i < images.length; ++i) {
			if (images[i].amgSkip()) {
				startIndex++;
				continue;
			}
			var returnValue = processTheImage(images[i]);
			if(returnValue == 1) {
				AOM.alert(AOM.localizeWithArgs("$$$/MediaGallery/JavaScript/cannotCreateFile=The target file cannot be created.\n (1) \n (2) \n (3) ",
				 ["$$$/MediaGallery/JavaScript/reasons=There are two possible reasons:",
				  "$$$/MediaGallery/JavaScript/diskIsFull=1. Disk space is insufficient.",
				 "$$$/MediaGallery/JavaScript/nameTooLong=2. The target file path is too long."]));
				taskManager.pause();
				taskManager.killTasks();
				taskManager.progress.close();
				imageCache.deleteLatest();
				return 0;
			}
			startIndex++;
			if (!images[i].allSizeExist) {
				break;
			}
		}
		return startIndex;
	}
	
	var processTheImage = function(image)
	{
		if (image.amgSkip()) {
			return true;
		}
		var imageFile;
		var allImagesHitInCache = true;
		for (var i in sizesList) {
			if (image.amg.sizes[i].needCreate)
				allImagesHitInCache = false;
		}

		// If all required images have already been in the cache, there will be no need for creating
		// new cache item in this function. Therefore, do not read bitmap data from the user-selected
		// image unless all images are not already in the cache.
		var imageBits;
		if (!allImagesHitInCache) {
			imageBits = imageCache.createBitmapData(image, sizesList);
			if(imageBits == undefined) {
				imageCache.createNullItem(image);
				AOM.AMG.Log.writeError("process image - could not get full bitmap for " + image.name);
				image.amgSkip(true);
				return 0;
			}
			if(image.rotation != 0) {
				var oldImage = imageBits;
				imageBits = imageBits.rotate(image.rotation);
				oldImage.dispose();
			}
		}
		
		for (var i in sizesList) {
			if (image.amg.sizes[i].needCreate) {
				// Web Gallery generates more than one images for one user-selected image file. So it may by
				// chance already cached an image which was uncached before the scheduled task. Check it here.
				testImage(image, i);
				if (!image.amg.sizes[i].needCreate) {
					imageFile = new File(image.amg.sizes[i].cacheImagePath);
				} else {
					var createResult = imageCache.createNewCacheItemFromBitmap(image, image.amg.sizes[i].demandInfo, imageBits, sizesList, jpegQuality);
					if (createResult.diskFull) {
						if(imageBits != undefined)
							imageBits.dispose();
						return 1;
					}
					image.amg.sizes[i].cacheImagePath = imageCache.tempImageCacheFolder + File.encode(createResult.tempFileName) + ".jpg";
					image.amg.sizes[i].width  = createResult.width;
					image.amg.sizes[i].height = createResult.height;
					imageFile = new File(image.amg.sizes[i].cacheImagePath);
				}
			} else {
				imageFile = new File(image.amg.sizes[i].cacheImagePath);
			}

			if (!imageFile.exists) {
				// A user must not delete cached images. If he/she does, it is also checked prior the
				// task. If the cached images are still missed at this point, it is really a user's fault.
				AOM.AMG.localize("$$$/MediaGallery/JavaScript/CacheFileMissed=Cache File Missed: " + imageFile);
			}

			var filePath = imagesFolder + "images/" + sizesList[i].size + "/";
			var jpgFile = AOM.AmgGalleryCreator.removeImageExtension(image.uri);
			if (image.amg.alteredName == undefined)
				image.amg.alteredName = AOM.AmgGalleryCreator.createUniqueFileName(filePath, jpgFile, createMode);
			var imagePath = filePath + image.amg.alteredName;
			
			if (AOM.AMG.verbose || log) AOM.AMG.Log.writeLine("processImage - imagePath is " + imagePath);
			image.amg.sizes[i].imagePath = imagePath;
			
			var f = new File(imagePath);
			if(!imageFile.copy(f)) {
				if(imageBits != undefined)
					imageBits.dispose();
				return 1;
			}
			if (f.exists && createMode != AOM.AmgGalleryCreator.createModes.preview &&
							createMode != AOM.AmgGalleryCreator.createModes.previewInBrowser) {
				var needCopyBack = false;
				var destThumb;
				var tempFile = new File(Folder.temp + "/CopyRightDestFile.jpg");
				
				try {
					// An exception will be thrown if f.fsName contains surrogate pair
					destThumb = new Thumbnail(f.fsName);
				} catch(e) {
					// If an exception is caught, transfer copyright to a temp file first, 
					// then copy it back to the dest file.
					if (!f.copy(tempFile)) {
						AOM.AMG.Log.writeError("processImage - transfer copyright failed (" + f.fsName + ")");
					} else {
						destThumb = new Thumbnail(tempFile);
						needCopyBack = true;
					}
				}
				
				AOM.AmgGalleryCreator.transferCopyright(image, destThumb, copyright);
				if (needCopyBack) {
					if (!tempFile.exists || !tempFile.copy(f)) {
						AOM.AMG.Log.writeError("processImage - transfer copyright failed (" + f.fsName + ")");
					}
				}
				if (tempFile.exists) {
					tempFile.remove();
				}
			} else if (!f.exists){
				AOM.AMG.Log.writeError("processImage - exportTo failed (" + f.fsName + ")");
			}
		}
		
		if (imageBits != undefined)
			imageBits.dispose();

		return 0;
	}

	var taskCount = 0;
	var existAtTail = false;
	
	for (var i = 0; i < images.length; ++i) {
		var image = images[i];
		testImage(image);
		if (image.amgSkip())
			continue;
		if (image.allSizeExist) {
			existAtTail = true;
		} else {
			taskCount++;
			existAtTail = false;
		}
	}
	if (existAtTail)
		taskCount++;
	taskManager.startGroup(AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/ProcessingImages=Processing images"), taskCount);
	// insert the completion callback
	taskManager.insertTask(onCompletionCallback.action, onCompletionCallback.description);
	var startIndex = 0;
	var f = function() {
        startIndex = processImage(images, startIndex);
    }
	if (existAtTail) {
		taskManager.insertTask(f, AOM.AMG.localize("$$$/MediaGallery/Javascript/GalleryCreator/ExistentImages=Loading images from cache"));
	}
	for (var i = 0; i < images.length; ++i) {
		var image = images[i];
		if (image.amgSkip())
			continue;
		if (!image.allSizeExist) {
			taskManager.insertTask(f, image.name);
		}
	}
}

AOM.AmgGalleryCreator.removeImageExtension = function(filePathName)
{
	filePathName = filePathName.replace(/^\s+|\s+$/g, "");
	if (/\.\w+$/.test(filePathName)) {
		if (filePathName.match(/([^\/\\]+)\.(\w+)$/)) {
			return RegExp.$1;
		} else {
			return filePathName;
		}
	} else {
		return filePathName;
	}
}

AOM.AmgGalleryCreator.removeIllegalChars = function(filename)
{
	// in order to avoid failing when transfer gallery between different os, 
	// remove illegal chars in filename of images on windows or mac osx. 
	return filename.replace( /[<>:"\\\/*\|;?]/g, "" );
}

AOM.AmgGalleryCreator.createUniqueFileName = function(filePath, jpgFile)
{
	var alteredName;
	var nameChanged = false;

	var convertFileName = AOM.BridgePreferences.getHasConvertMultibyte();
	convertFileName = (convertFileName == undefined) || (convertFileName == "true");
	
	jpgFile = AOM.AmgGalleryCreator.removeIllegalChars(File.decode(jpgFile));
	if (jpgFile == "")
		nameChanged = true;
	
	if (convertFileName)
	{
		for (var j = jpgFile.length - 1; j >= 0; j--)
		{
			if (jpgFile.charCodeAt(j) >= 128)
			{
				nameChanged = true;
				jpgFile = "";
				break;
			}
		}
	}

	jpgFile = File.encode( jpgFile );

	if (!nameChanged)
	{
		alteredName = jpgFile + ".jpg";
		var f = new File(filePath + alteredName);
		if (f.exists)
			nameChanged = true;
	}
	
	if (nameChanged)
	{
		var idx = 1;
		while (true)
		{
			alteredName = jpgFile + "_" + idx + ".jpg";
			var f = new File(filePath + alteredName);
			if (f.exists)
				idx++;
			else
				break;
		}
	}
	return alteredName;
}

AOM.AmgGalleryCreator.transferCopyright = function (source, dest, defaultCopyright)
{
	if (source == undefined || !source instanceof Thumbnail)
		return AOM.AmgGalleryCreator.transferCopyright.error("source not Thumbnail");
	
	if (dest == undefined || !dest instanceof Thumbnail)
		return AOM.AmgGalleryCreator.transferCopyright.error("dest not Thumbnail");

	try {
		// Init AdobeXMPScript external object 
		AOM.XMPUtil.loadXMPLib();
		
		// Get synchronous destination thumbnail XMPMeta object.
		var destXMPMeta = new XMPMeta(dest.synchronousMetadata.serialize());
		
		// Update some metadata infos.
		var appName = "Adobe Bridge " + AOM.CS_VERSION + " (" + (File.fs == "Macintosh" ? "Macintosh" : "Windows") + ")";
		AOM.XMPUtil.setStringProp(destXMPMeta, XMPConst.NS_XMP, "CreatorTool", appName);
				
		// Get synchronous source thumbnail XMPMeta object.
		if (source.core.itemContent.canGetXmp) {
			var srcXMPMeta = new XMPMeta(source.synchronousMetadata.serialize());
			
			var rights = AOM.XMPUtil.getArrayProp(srcXMPMeta, XMPConst.NS_DC, "rights");
			if (rights == undefined) {
				if (defaultCopyright != undefined && defaultCopyright.length > 0) {
					rights = [defaultCopyright];
				}
			}
			AOM.XMPUtil.setArrayProp(destXMPMeta, XMPConst.NS_DC, "rights", rights);
			
			var marked = AOM.XMPUtil.getStringProp(srcXMPMeta, XMPConst.NS_XMP_RIGHTS, "Marked");
			AOM.XMPUtil.setStringProp(destXMPMeta, XMPConst.NS_XMP_RIGHTS, "Marked", marked);
			
			var webStatement = AOM.XMPUtil.getStringProp(srcXMPMeta, XMPConst.NS_XMP_RIGHTS, "WebStatement");
			AOM.XMPUtil.setStringProp(destXMPMeta, XMPConst.NS_XMP_RIGHTS, "WebStatement", webStatement);
			
			var usageTerms = AOM.XMPUtil.getArrayProp(srcXMPMeta, XMPConst.NS_XMP_RIGHTS, "UsageTerms");
			AOM.XMPUtil.setArrayProp(destXMPMeta, XMPConst.NS_XMP_RIGHTS, "UsageTerms", usageTerms);
		} else {
			if (defaultCopyright != undefined && defaultCopyright.length > 0) {
				AOM.XMPUtil.setArrayProp(destXMPMeta, XMPConst.NS_DC, "rights", [defaultCopyright]);
			}
		}
		
		// Write metadata back to the destination file.
		var xmp = new XMPFile(dest.path, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
		if (xmp.canPutXMP(destXMPMeta)) {
			xmp.putXMP(destXMPMeta);
		}
		xmp.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
	} catch(e) {
		AOM.AMG.Log.writeError("Processing meta-data: " + e);
	}

	return;
}
AOM.AmgGalleryCreator.transferCopyright.error = function (s)
{
	return AOM.AMG.Log.writeError("AOM.AmgGalleryCreator.processImage.transferCopyright - " + s);
}
AOM.AmgGalleryCreator.previewPrep = function (images)
{
	// truncate images array to the first 10 not marked to skip 
	if (images.length > 20)
	{
		var imageCount = 0;
		for (var i = 0; i < images.length; i++)
		{
			var image = images[i];
			if (image.amgSkip())
				continue;
			imageCount++;
			if (imageCount > 20) {
				images.length = i; // truncate the array and fall out of loop
			}
		}
	}
}
AOM.AmgGalleryCreator.imagePrep = function (images)
{
	var count = 0;
	for (var i = 0; i < images.length; i++)
	{
		var image = images[i];
		image.amg = {};
		if (image.amgIsImage(false)) // Note - do we want to skip the bitmap level check?
			count++
		else
			image.amgSkip(true);
	}
	return count;
}
AOM.AmgGalleryCreator.checkNotEmpty = function (value, fieldName)
{
	if (value.amgIsEmpty())
	{
		AOM.alert(fieldName + " " + AOM.AMG.localize("$$$/MediaGallery/JavaScript/fieldMustNotBeBlank=field must not be blank."));
		return false;
	}
	return true;
}
AOM.AmgGalleryCreator.checkValidPath = function(value, fieldName)
{
	if (!value.amgIsValidPath())
	{
		var alertMessage = AOM.AMG.localize(fieldName);
		alertMessage += " " + AOM.AMG.localize("$$$/MediaGallery/JavaScript/pathInvalidCharacter=The path contains an invalid character.");
		alertMessage += "\n(" + AOM.AMG.badPathCharacters().toString() + ")";
		AOM.alert(alertMessage);
		return false;
	}
	// Bridge can't write to root of Mac so watch for that too
	if (File.fs == "Macintosh" && value.amgTrim() == "/")
	{
		AOM.alert(AOM.AMG.localize("$$$/MediaGallery/JavaScript/GalleryCreator/NotAllowSaveRoot=Gallery cannot be saved at the root."));
		return false
	}
	return true;
}
AOM.AmgGalleryCreator.checkValidFile = function(value, fieldName)
{
	if (!value.amgIsValidFile())
	{
		var alertMessage = AOM.AMG.localize(fieldName);
		alertMessage += " " + AOM.AMG.localize("$$$/MediaGallery/JavaScript/pathInvalidCharacter=The path contains an invalid character.");
		alertMessage += "\n(" + String.badFileCharacters().toString() + ")";
		AOM.alert(alertMessage);
		return false;
	}
	return true;
}
AOM.AmgGalleryCreator.checkValidUser = function (value, fieldName)
{
	if (/[:]/.test(value))
	{
		AOM.alert(AOM.localizeWithArgs("$$$/ContactSheet/javascript/validation/illegalPasswordChar=(1) includes illegal characters.", fieldName) + " [:]");
		return false;
	}
	return true;
}

AOM.XMPUtil = function() {
	//
}

AOM.XMPUtil.loadXMPLib = function() {
	if(AOM.XMPUtil.XMPExternal == undefined) {
		AOM.XMPUtil.XMPExternal = new ExternalObject("lib:AdobeXMPScript");
	}
}

AOM.XMPUtil.getStringProp = function(xmpMeta, schemaNS, propName) {
	return xmpMeta.getProperty(schemaNS, propName);
}

AOM.XMPUtil.getArrayProp = function(xmpMeta, schemaNS, propName) {
	var items = [];
	if (xmpMeta.doesPropertyExist(schemaNS, propName)) {
		var itemCount = xmpMeta.countArrayItems(schemaNS, propName);
		for (var i = 0; i < itemCount; ++i) {
			items[i] = xmpMeta.getArrayItem(schemaNS, propName, i + 1);
		}
	} else {
		items = undefined;
	}
	return items;
}

AOM.XMPUtil.setStringProp = function(xmpMeta, schemaNS, propName, propValue) {
	xmpMeta.deleteProperty(schemaNS, propName);
	
	if (propValue != undefined) {
		xmpMeta.setProperty(schemaNS, propName, propValue);
	}
}

AOM.XMPUtil.setArrayProp = function(xmpMeta, schemaNS, propName, propArray) {
	xmpMeta.deleteProperty(schemaNS, propName);
	
	if (propArray != undefined) {
		for (var i = 0; i < propArray.length; ++i) {
			xmpMeta.appendArrayItem(schemaNS, propName, propArray[i], 0, XMPConst.ARRAY_IS_ORDERED);
		}
	}
}

AOM.PreviewFormData = function(previewInBrowser, previewFunction, document, previewMode)
{
	this.valid = true;
	this.createMode = previewMode;
	this.previewInBrowser = previewInBrowser;
	this.previewFunction = previewFunction;
	this.document = document;
	this.documentID = document.id;
}
AOM.SaveToDiskFormData = function(galleryName, saveLocation, document)
{
	// validity tests
	this.valid = false;
	if (!AOM.SaveToDiskFormData.isValidField(galleryName, "$$$/MediaGallery/JavaScript/galleryName=Gallery Name:"))
		return false;
	if (!AOM.SaveToDiskFormData.isValidField(saveLocation, "$$$/MediaGallery/JavaScript/saveLoc=Save Location:"))
		return false;
	
	// if we're here, all's ok	
	this.valid = true;
	this.createMode = AOM.AmgGalleryCreator.createModes.saveToDisk;
	this.galleryName = galleryName;
	this.saveLocation = saveLocation;
	this.document = document;
	this.documentID = document.id;
}
AOM.SaveToDiskFormData.isValidField = function(value, fieldName)
{
	var checkNotEmpty = false;
	var checkValidPath = false;
	var checkValidFile = false;
	switch(fieldName)
	{
	case "$$$/MediaGallery/JavaScript/galleryName=Gallery Name:":
		checkNotEmpty = true;
		checkValidFile = true;
		break;
	case "$$$/MediaGallery/JavaScript/saveLoc=Save Location:":
		checkNotEmpty = true;
		checkValidPath = true;
		break;
	default:
		AOM.alert(AOM.AMG.localize("$$$/private/saveDiskFormDataUnknownFieldName=AOM.SaveToDiskFormData.isValidField - unknown fieldName."));
		return false;
		break;
	}
	fieldName = AOM.AMG.localize(fieldName);
	if (checkNotEmpty && AOM.AmgGalleryCreator.checkNotEmpty(value, fieldName) == false)
		return false;
	if (checkValidPath && AOM.AmgGalleryCreator.checkValidPath(value, fieldName) == false)
		return false;
	if (checkValidFile && AOM.AmgGalleryCreator.checkValidFile(value, fieldName) == false)
		return false;
	return true;
}
AOM.UploadFormData = function(galleryName, ftpServer, userName, password, uploadFolder, document)
{
	// validity tests
	this.valid = false;
	if (!AOM.UploadFormData.isValidField(galleryName, "$$$/MediaGallery/JavaScript/galleryName=Gallery Name:"))
		return false;
	if (!AOM.UploadFormData.isValidField(ftpServer, "$$$/MediaGallery/JavaScript/ftpserver=FTP Server:"))
		return false;
	if (!AOM.UploadFormData.isValidField(userName, "$$$/MediaGallery/JavaScript/username=User Name:"))
		return false;
	if (!AOM.UploadFormData.isValidField(password, "$$$/MediaGallery/JavaScript/password=Password:"))
		return false;
	if (!AOM.UploadFormData.isValidField(uploadFolder, "$$$/MediaGallery/JavaScript/uploadfolder=Folder:"))
		return false;
	
	// if we're here, all's ok	
	this.valid = true;
	this.createMode = AOM.AmgGalleryCreator.createModes.upload;
	this.galleryName  = galleryName.amgTrim();
	this.ftpServer    = ftpServer.amgTrim();
	
	/*check  if userName is emtpy , set anonymous.*/
	if (userName == undefined || userName.length == 0) {
		if (password == undefined || password.length == 0) {
			this.userName = "";
			this.password = "";
		} else {
			this.userName = "anonymous";
			this.password = password;
		}
	} else {
		this.userName = userName;
		this.password = password;
	}
	
	this.uploadFolder = uploadFolder.amgTrim();
	this.document = document;
	this.documentID = document.id;
}
AOM.UploadFormData.isValidField = function(value, fieldName)
{
    if (value == undefined)
        return false;
	var checkNotEmpty = false;
	var checkValidPath = false;
	var checkValidFile = false;
	var checkValidUser = false;
	switch(fieldName)
	{
	case "$$$/MediaGallery/JavaScript/password=Password:":
	case "$$$/MediaGallery/JavaScript/uploadfolder=Folder:":
		// if we knew the destination file system we could check upload folder for valid file path
		return true;
		break;
	case "$$$/MediaGallery/JavaScript/galleryName=Gallery Name:":
		checkNotEmpty = true;
		checkValidFile = true;
		break;
	case "$$$/MediaGallery/JavaScript/username=User Name:":
		checkValidUser = true;
		break;
	case "$$$/MediaGallery/JavaScript/ftpserver=FTP Server:":
		checkNotEmpty = true;
		break;
	default:
		AOM.alert(AOM.AMG.localize("$$$/private/uploadFormDataUnknownFieldName=AOM.UploadFormData.isValid - unknown fieldName."));
		return false;
		break;
	}
	fieldName = AOM.AMG.localize(fieldName) ;
	if (checkNotEmpty && AOM.AmgGalleryCreator.checkNotEmpty(value, fieldName) == false)
		return false;
	if (checkValidPath && AOM.AmgGalleryCreator.checkValidPath(value, fieldName) == false)
		return false;
	if (checkValidFile && AOM.AmgGalleryCreator.checkValidFile(value, fieldName) == false)
		return false;
	if (checkValidUser && AOM.AmgGalleryCreator.checkValidUser(value, fieldName) == false)
		return false;
	return true;
}
