﻿/**
 * @author $Author: rhorns $
 * @date $DateTime: 2009/03/06 11:12:40 $
 * @version	$Revision: #2 $
 * 
 * ADOBE CONFIDENTIAL
 *
 * Copyright 1997-2007 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.
*/

#include "../shared/dmppanel.jsx"

//-----------------------------------------------------------------------------
//
// Utilities
//
//-----------------------------------------------------------------------------

function ReviewPanelUtilities() {
}

// this is a wrapper that takes care of logging, handling exceptions and return values
ReviewPanelUtilities.callMainFunction = function(entryPointFunction) {
	try {
		// construct a new argument array for the function
		var args = [];
		for(var i = 1; i<arguments.length; i++) {
			args.push (arguments[i]);
		}
	
		// call the entry point function with the remaining arguments
		var result = entryPointFunction.apply(undefined, args);
        
	} catch (x1) {
		return "<string><![CDATA[<error>" + x1 +  "</error>]]></string>";
	}
	return "<string><![CDATA[" + result +  "]]></string>";
}

//********************************************************************************************
// Utils.fixPathIfNeeded
//
// Windows-specific file path fix
//********************************************************************************************

ReviewPanelUtilities.fixPathIfNeeded = function(pathIn, checkForWindowsOS)
{
	var path = pathIn;
	var validOS = true;
	if(checkForWindowsOS) {
		if(File.fs == 'Windows') 
			validOS = true;
		else
			validOS = false;
	}
	if (RegExp("^file:///").test(path) && validOS) 
	{
		// On Windows, paths of the form 'file:///c:/etc' will fail -- it's that third
		// slash that throws it off. So replace the /// with //. -MJP
		// enabling this code for Mac -roey
		
		// Test if the path is in the form of file:////*. This will happen when file is on an
		// unmapped network drive on Windows. 
		if (RegExp("^file:////").test(path)) {
			path = path.substr(7); // Convert the file path from file:////* to //* so that javascript can understand
		}
		else {
			path = path.substr(0,7) + path.substr(8);
		}
	}
	return path;
}

//********************************************************************************************
// ReviewPanelUtilities.fixVolumeIfNeeded
//
// This is Mac specific. Extendscript has a limitation where, if the name of the local directory
// under the root volume is the same as one of the mounted volumes, then there is no way to 
// uniquely specify the path to a file inside the local directory.
//
// i.e. Assume there is local directory called Transfer under the root volume and it contains
// a file named Illustrator.jsx. Also, there is mounted volume called Transfer. Due to the limitation
// there is no way to create a File object which points to /Transfer/Illustrator.jsx under the
// root volume. ExtendScript always gives priority to the mounted volume if there is a name clash
// and will try to find the file Illustrator.jsx under the mounted volume 'Transfer'.
//
// The fix here is to catch such cases and change the file name such that ExtendScript points 
// to the file on the local file system.
//
// We catch such cases by looking for the file path in the extendScript File object and the file
// path we got from ActionScript.
//
// eg. filePath from AS = file:///Transfer/Illustrator.jsx and
//	   filePath in ES = /Volumes/Transfer/Illustrator.jsx
//
// Here we can see that the filePath in ES was wrongly redirected to the remote file system. The
// way we fix this is by inserting the name of the root volume in between. So if the name
// of the root volume is MacintoshHD, then the returned path will be
// /Volumes/MacintoshHD/Transfer/Illustrator.jsx
//
// It is also possible that user actually referred to the file on the mounted file system. In those cases,
// the file url from ActionScript should be file:///Volumes/... We detect this in the second if loop,
// and prevent any changes to the filePath in ES in such cases.
//
// This shouldn't be a problem on Windows as each remote volume is identified by a separate alphabet.
//********************************************************************************************

ReviewPanelUtilities.fixVolumeIfNeeded = function (path, rootVolumeName) 
{
    var fileAtPath = File (path);
    // 1) We have rootVolumeName. This will be null on windows
    // 2) Check if the ExtenScript path includes a /Volumes in the beginning. If not, then we can ignore
    if (rootVolumeName != 'null' && RegExp("^/Volumes").test(fileAtPath.fsName)) {
    	
    	// Check if the path is in the form of url. This will happen when the path is formed in ActionScript.
    	if (RegExp("^file:///").test(path)) {
	                
	        // Now decide which location should get preference. The remote volume or the local directory under the root volume
	        // If the ActionScript path starts with file:///Volumes, then remote volume should get the preference.
	        if (RegExp("^file:///Volumes").test(path)) {
	             return path;
	        }
	        else {
	              // The user intended to access the local volume
	              // Try to construct a local path
	              var newPath = "/Volumes/"+rootVolumeName+fileAtPath.fullName;
	              // Check if the file exists at that location
	              var newFile = File (newPath);
	              // This is just to be safe.
	              if (newFile.exists)
	              	return newPath;
	        }
	    }
    }
    return path;
}

//********************************************************************************************
// scriptAlert
//
// shows an alert
//********************************************************************************************

var scriptAlert = function(msg)
{
	return ReviewPanelUtilities.callMainFunction(_scriptAlert, msg);
}

var _scriptAlert = function(msg)
{
	alert(msg);
	return "<success />";
}

//********************************************************************************************
// getDocumentList
//
// returns an XML snippet that contains information on the open documents
//********************************************************************************************

var getDocumentList = function () {
	return ReviewPanelUtilities.callMainFunction(_getDocumentList);
}

var _getDocumentList = function () {
	return app.getDocumentsIds();
}

//********************************************************************************************
// getDocument
//
// Get the Indesign document for the specified file. Open the document in InDesign
// if openIfNecessary is true.
//********************************************************************************************
function getDocument(inddFile, openIfNecessary)
{
	if(!openIfNecessary)
		openIfNecessary = false;
	
	if(!inddFile || !inddFile.exists)
		return null;

	// Apparently, asking for some File.name returns a URI encoded string... 
	//var decodedName = decodeURIComponent(inddFile.name);

	// see if the document is already open...
	var numDocs = app.documents.length;
	for(var i = 0; i < numDocs; i++)
	{
		var d = app.documents[i];
         var file = d.fullName;
		if(file && file.fsName == inddFile.fsName)
		{
			/*
				Note: this doesn't guarantee a perfect match, but it's very likely
				that we're grabbing the correct document. We could try to base things on
				the document's file name, but if there are any link problems or
				conversions that took place, (likely), then asking for the file
				will fail because the current version of the document is unsaved.
				An exception will be thrown, and we won't make a match.
			*/
 			return d;
		}
	}
	 
	// turn off user interaction.
	var userInteractionLevel = app.scriptPreferences.userInteractionLevel;UserInteractionLevels
	app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;

	var doc = openIfNecessary? app.open(inddFile) : null;
	
	// turn back user interaction.
	app.scriptPreferences.userInteractionLevel = userInteractionLevel;
	
	return doc;
}

//********************************************************************************************
// getDocumentInfo
//
// returns information about the specified document.
//********************************************************************************************

var getDocumentInfo = function (args) {
 	return ReviewPanelUtilities.callMainFunction(_getDocumentInfo, args);
}

var _getDocumentInfo = function (args) {
    var arguments = new XML(args);

	var inddFile = new File(arguments.@file.toString());
     var doc = getDocument(inddFile, arguments.@openIfNeed.toString() == 'true');

	var docInfo = new XML('<docInfo><isDirty /></docInfo>');
 	if(doc != null && doc != undefined) {
        docInfo.isDirty.setChildren(doc.modified ? 'true' : 'false');
	}
	return docInfo.toXMLString();
}

//********************************************************************************************
// generateMiniBundle
//
// exports mini bundle as the specified output file.
//********************************************************************************************

var generateMiniBundle = function (args) {
	return ReviewPanelUtilities.callMainFunction(_generateMiniBundle, args);
}

var _generateMiniBundle = function (args) {
    var arguments = new XML(args);

    var inddFile1 = new File(arguments.@vPath.toString());
    var doc1 = inddFile1 ? getDocument(inddFile1, false) : null;
    
    var inddFile2 = new File(arguments.@hPath.toString());
    var doc2 = inddFile2 ? getDocument(inddFile2, false) : null;
   
    var jpegQuality;
    switch (arguments.@jpegQuality.toString())
    {
        case 'minimum':
            jpegQuality = DynamicDocumentsJPEGQualityOptions.MINIMUM;
            break;
            
        case 'low':
            jpegQuality = DynamicDocumentsJPEGQualityOptions.LOW;
            break;
            
        case 'medium':
            jpegQuality = DynamicDocumentsJPEGQualityOptions.MEDIUM;
            break;
            
        case 'high':
            jpegQuality = DynamicDocumentsJPEGQualityOptions.HIGH;
            break;
            
        case 'maximum':
            jpegQuality = DynamicDocumentsJPEGQualityOptions.MAXIMUM;
            break;
     }

    var outFile = new File(arguments.@outputBundle.toString());
    var miniIssueParams = [
                                ["assetformat", arguments.@assetFormat.toString()],   
                                ["jpegquality", jpegQuality],
                                ["narrowdimensions", parseInt(arguments.@vWidth.toString())],
                                ["widedimensions", parseInt(arguments.@hWidth.toString())],
                             ];
    var metaData = [
                                ["title", arguments.@title.toString()],
                                ["author", arguments.@author.toString()],
                                ["kicker", arguments.@kicker.toString()],
                                ["description", arguments.@description.toString()],
                                ["tags", arguments.@tags.toString()],
                                ["isAdvertisement", arguments.@isAds.toString()],
                            ];

            
    //alert("Start exporting mini issue...");
    app.exportMiniFolio(doc1, doc2, outFile, miniIssueParams, metaData);
    //alert("End exporting mini issue...");
}

//********************************************************************************************
// isDocumentSaved
//
// This method determines whether the document has an associated file-name
// If not, it returns an error
//********************************************************************************************

var isDocumentSaved = function(doc)
{
	return ReviewPanelUtilities.callMainFunction(_isDocumentSaved, doc);
}
var _isDocumentSaved = function(doc)
{
	try
	{
		var name = doc.fullName;
	}
	catch (e)
	{
		return "false";
	}
	return "true";
}

//********************************************************************************************
// saveDocument
//
// Saves the document at the location specified in the argument
//********************************************************************************************

var saveDocument = function(args)
{
	return ReviewPanelUtilities.callMainFunction(_saveDocument, args);
}
var _saveDocument = function(args)
{
    var arguments = new XML(args);
    var showSaveAsDialog = arguments.@showSaveAsDialog.toString() == 'true';
    
    if(showSaveAsDialog) {
        // we have to invoke the Save As menu action
        const saveAsKey = '$ID/Save &As...';
        var localizedActionName = app.translateKeyString(saveAsKey);
        var action = app.menuActions.itemByName(localizedActionName);
        action.invoke();
    } else {
        // we can simply call save
        app.activeDocument.save();
     }
}

//********************************************************************************************
// getDocumentId
//
// Returns the document ID at the file path specified in the argument
//********************************************************************************************

var getDocumentId = function (args) {
	return ReviewPanelUtilities.callMainFunction(_getDocumentId, args);
}

var _getDocumentId = function (args) {
	var retval = new XML('<success />');
	var arguments = new XML(args);
    var path = arguments.@filePath.toString();
    var rootVolume = arguments.@rootVolumeName.toString();
    path = ReviewPanelUtilities.fixPathIfNeeded(path, 1);
    path = ReviewPanelUtilities.fixVolumeIfNeeded(path, rootVolume);
    var myFile = File(path);
    var doc = app.open (myFile, false);
    var instanceId = doc.metadataPreferences.getProperty('http://ns.adobe.com/xap/1.0/mm/', 'InstanceID');
    instanceId = instanceId.split(':').pop();
    var original = new XML('<instance id="'+instanceId+'"/>');
    retval.appendChild(original);
	return retval;
}

//********************************************************************************************
// cancelTask
//
// cancels the task identified by taskId
//********************************************************************************************

var cancelTask = function(args) {
	return ReviewPanelUtilities.callMainFunction(_cancelTask, args);
}

var _cancelTask = function(args) {
	var arguments = new XML(args);
    var taskId = parseInt(arguments.@taskId.toString());
    var task = app.backgroundTasks.itemByID(taskId);
    task.cancelTask();
    return "<success />";
}


