/**
 * @author $Author: kmattson $
 * @date $DateTime: 2009/02/11 08:02:48 $
 * @version	$Revision: #1 $
 * 
 * ADOBE CONFIDENTIAL
 *
 * Copyright 1997-2009 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.
*/


//-----------------------------------------------------------------------------
//--------  BEGIN   BUG  2334616     -------------------------------------
//-----------------------------------------------------------------------------
//
//
//
// #include "./reviewpanel-shared.jsx"
//
//
//  As per bug#2334616, we can't yet use #include in CSXS, so instead 
//    the contents of it is duplicated below. If you have to change this
//    code before the bug is fixed, please also change reviewpanel-shared.jsx
//    as well as the other apps' scripts
//

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)
{
	var path = pathIn;
	if(File.fs == 'Windows') {
        if (RegExp("^file:///").test(path)) 
        {
            // 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
            path = path.substr(0,7) + path.substr(8);
        }
    }
	return path;
}


//-----------------------------------------------------------------------------
//--------  END   BUG  2334616     -------------------------------------
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
//
// Entry Points
//
//-----------------------------------------------------------------------------

var getCSXSCredentials = function () {
	return ReviewPanelUtilities.callMainFunction(_getCSXSCredentials);
}

function _getCSXSCredentials() {
//	alert('jmork: about to return hardcoded credentials!');
    return '<credentials username="' + emailAddress + '" password="' + password + '" />';
}


//********************************************************************************************
// getEventsSupport
//
// determines whether the application support events to notify of selection and document changes
//********************************************************************************************

var getEventsSupport = function () {
	return ReviewPanelUtilities.callMainFunction(_getEventsSupport);
}

function _getEventsSupport() {
    return "<root><eventsSupported>false</eventsSupported></root>";

}


//********************************************************************************************
// getDocumentList
//
// returns an XML snippet that contains information on the open documents
//
// Notice that for Photoshop we currently don't list all open documents since we are only interested in the active one
//********************************************************************************************

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

var _getDocumentList = function () {
	var list = new XML('<documents />');
	
	// The active sequence becomes the pseude active document

	if (
		(app.project != undefined) &&
		(app.project.activeSequence != undefined) &&
		(app.project.activeSequence.end > 0)
	) {
		list.@activeDocument = app.project.activeSequence.sequenceID;
	}		
	
	// Fetch all the sequences that belong to the currently active project
	var sequences = app.project.sequences;

	var projectName = app.project.name;
	list.@projectName = projectName;
	
	var document;
	var id;
	var name;
	// Loop through all the sequences and store their sequence id and name
	for(var count = 0; count < sequences.numSequences; count++)
	{
        var sequence = sequences[count];
		document = new XML("<document />");
		id = sequence.sequenceID;
		name = sequence.name;
		document.@id = id;
		document.@name = name;
		list.appendChild(document);
	}
	return list.toXMLString();
}

//********************************************************************************************
// getSequenceName
//
// returns name of the active sequence
//********************************************************************************************

var getSequenceName = function () {
	return ReviewPanelUtilities.callMainFunction(_getSequenceName);
}

var _getSequenceName = function () {
	var retval = new XML('<success />');
	retval.appendChild(app.project.activeSequence.name);
	return retval;
}



//********************************************************************************************
// jumpToComment
//
// brings the document to front, goes to the spread and centers the comment in the window
//********************************************************************************************

var jumpToComment = function (args) {
	return ReviewPanelUtilities.callMainFunction(_jumpToComment, args);
}

var _jumpToComment = function (args) {
	var arguments = new XML(args);
     var comment = new XML(arguments.@comment.toString());
    app.project.activeSequence.setPlayerPosition(comment.@time);
	return "<success />";
}

//********************************************************************************************
// openFile
//
// Opens the project file associated with the sequence
//********************************************************************************************

var openFile = function (args) {
	return ReviewPanelUtilities.callMainFunction(_openFile, args);
}

var _openFile = function (args) 
{
	var arguments = new XML(args);
	var retval = "<success />";

	// open the file
	var path = arguments.@filePath.toString();
	var sequenceId = arguments.@instanceId.toString();
	var isSameApp = arguments.@sameApp.toString();
	// Check if the path is NA - this means the user had not saved the project/document.
	// Projects should always have a path. Hence we return error by default as this condition
	// will only be satisfied if isSameApp = false
	if(path == "NA") 
	{
		retval = "<error/>";	
	}
	else
	{
		// First check whether the part originated from Premiere Pro
		// If not, then we can directly skip this action
		if (isSameApp == "true")
		{
			path = ReviewPanelUtilities.fixPathIfNeeded(path, 1);
			var result = openProjectWithSequence(path, sequenceId);
			if (! result)
				retval = "<error/>";
		}
		else
		{
			retval = "<error/>";
		}
	}
	return retval;
}
//********************************************************************************************
// isProjectOpen
//
// Tests whether the project currently open is what we want
// If the project is open, it sets the active sequence to the sequence id
//********************************************************************************************
function isProjectOpen (sequenceId, path)
{
	var retval = false;
	var project = app.project;
	if(project != null && project != 'undefined')
	{	
		var projPath = project.path;
		if(projPath != 'undefined')
		{
			projPath = fixProjectPath(projPath);
		}
		// We cannot compare the paths directly as path variable may be in the form of url
		var file1 = File(projPath);
		var file2 = File(path);
		if(file1.exists && file2.exists && file1.fullName == file2.fullName)
		{
			// TEST if the sequence belongs to this project.
			var sequences = app.project.sequences;
			for(var count = 0; count < sequences.numSequences;count++)
			{
                var sequence = sequences[count];
				if(sequence.sequenceID == sequenceId)
				{
					//TODO - make the sequence active
					retval = true;
					break;
				}
			}
		}
	} 
	return retval;
}

var openFileAtPath = function (args) 
{
	return ReviewPanelUtilities.callMainFunction(_openFileAtPath, args);
}

var _openFileAtPath = function (args) 
{
	var arguments = new XML(args);
	var retval = "<success />";
	
	var path = arguments.@filePath.toString();
	path = ReviewPanelUtilities.fixPathIfNeeded(path, 1);
	var myFile = File(path);
	var isSameApp = arguments.@sameApp.toString();
    if(myFile.exists) {
        if(isSameApp == "true") {
	    	try {
				var sequenceId = arguments.@instanceId.toString();
				var result = openProjectWithSequence(path, sequenceId);
	    		if (! result)
	    			return ("<error/>");
	    	}
	    	catch(e) {
	    		
	    	}
	    }
		myFile.execute();
    }
	else {
		// try to open the file using the url
		retval = "<error/>";
	}
	return retval;
}


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

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

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


//********************************************************************************************
// getGuid
//
// gets GUID of active sequence
//********************************************************************************************

function getGuid() {
	return ReviewPanelUtilities.callMainFunction(_getGuid);
}

function _getGuid() {
	return app.project.activeSequence.sequenceID;
}

// Premiere pro returns the project path in the form of
// '\\?\C:\project\project.prproj'
// These back slashes do not go down well with premiere pro
function fixProjectPath(path) {
	if(File.fs == 'Windows')
	{
		// Replace all backslashes with forward slashes
		path = path.replace (/\\/g, "/");

		// Replace the initial junk characters
		if(path.indexOf('//?/') == 0)
		{
			path = path.substring(4);
		}
	}
	return path;
}

//********************************************************************************************
// getActiveDocument
//
// returns an XML snippet that contains information on the currently active document
//********************************************************************************************

var getActiveDocument = function () {
	return ReviewPanelUtilities.callMainFunction(_getActiveDocument);
}

var _getActiveDocument = function () {
    var doc = app.project.activeSequence;
    var document = new XML("<document />");
    document.@name = doc.name;
    var guid = _getGuid();
    if(guid != null) {
        document.@id = guid;
    }
	
	return document.toXMLString();
}



//********************************************************************************************
// generateContentsFromDocument
//
// generates contents, structure and previews of the whole document
//********************************************************************************************

var generateContentsFromDocument = function(args) {
	return ReviewPanelUtilities.callMainFunction(_generateContentsFromDocument, args);
}

var _generateContentsFromDocument = function (args) {
	var generator = new ContentsGenerator();
	var arguments = new XML(args);
	var result = generator.generateContentsOfDocument(app.activeDocument,  ReviewPanelUtilities.fixPathIfNeeded(arguments.@previewFile), 
																		parseInt(arguments.@previewWidth.toString()), 
																		parseInt(arguments.@previewHeight.toString()),  
																		ReviewPanelUtilities.fixPathIfNeeded(arguments.@contentFile),
																		arguments.@docId);
	return result.toXMLString();
}


//-----------------------------------------------------------------------------
//
// ContentsGenerator
//
//-----------------------------------------------------------------------------


//********************************************************************************************
// ContentsGenerator
//
// Generates the contents.xml file for a document
//********************************************************************************************

function ContentsGenerator() {
}

//********************************************************************************************
// 
// generateContentsOfDocument
//
// main function of the contents generator
//********************************************************************************************

ContentsGenerator.prototype.generateContentsOfDocument = function(doc, previewPath, previewWidth, previewHeight, contentPath, docId) {
	this.guid = _getGuid(doc);
	if(this.guid == null) {
		this.guid = docId;
	}
	// initialize properties
	this.contents = new XML('<contents />');
	
	this.parts = new XML('<parts />');
	
	// build the data model
			var partData = new XML('<part />');
			partData.@type = "video";
			partData.@id = this.guid;
			partData.@documentId = this.guid;
			partData.@originalFrameRate = app.project.activeSequence.timebase;

			partData.@originalHeight = app.project.activeSequence.frameSizeVertical;
			partData.@originalWidth  = app.project.activeSequence.frameSizeHorizontal;

			var videoData = new XML('<video />');
			videoData.@id = this.guid;
			this.parts.appendChild(videoData);

			this.contents.appendChild(partData);
				
			var previewData = new XML('<previews />');
			
			jobId = app.encoder.encodeForCSReview(app.project.activeSequence, contentPath, previewPath, previewHeight, previewWidth, 'PNG');
            
            //force extensions until Premiere honors a path with no extension.
	        previewData.appendChild(new XML('<preview partId="' +  this.guid + '" type="video" thumbnail="' + previewPath + '.png' + '" >' + contentPath + '.f4v' + '</preview>'));
		
			var result = new XML('<result documentId="' + this.guid + '" jobId="' + jobId + '" />');
			result.appendChild(this.contents);
			result.appendChild(this.parts);
			result.appendChild(previewData);
		
			result = this.appendMetadata(result, doc);
	
	return result;
}

//********************************************************************************************
// 
// appendMetadata
//
// appends metadata to contents xml
 //********************************************************************************************

ContentsGenerator.prototype.appendMetadata = function(data, doc) {
		var result = new XML(data);
		var metadata = new XML('<metadata />');
		
		var instanceId = _getGuid();
		var instanceDetails = new XML('<instanceIdAtReview id="'+instanceId+'"/>');
		var projectPath = app.project.path;
		projectPath = fixProjectPath(projectPath);
		var path = new XML('<filePath path="' + projectPath + '"/>');
		
		metadata.appendChild (instanceDetails);
		metadata.appendChild (path);
		
		result.appendChild (metadata);
	return result;
}


//-----------------------------------------------------------------------------
//
// Job Management
//
//-----------------------------------------------------------------------------


//********************************************************************************************
// 
// getJobStatus
//
// cancels rendering job
//********************************************************************************************

// jmork: Switchback will use this to get status of a rendering request from Premiere
function getJobStatus( jobId )
{
//	return encoder.getJobStatus( jobId )
}

//********************************************************************************************
// 
// cancelJob
//
// cancels rendering job
//********************************************************************************************

// jmork: Switchback will use this to notify Premiere of a cancellation to a rendering request
function cancelJob(jobId)
{
//	return app.encoder.cancelJob( jobId )
}

//********************************************************************************************
// 
// openProjectWithSequence
//
// open a project and a sequence
//********************************************************************************************

function openProjectWithSequence(path, sequenceId) {
	var myFile = File(path);
	if (myFile.exists) {
		if (app.project.path != path)
			app.openDocument(path);
		return (app.project.openSequence(sequenceId));
	} else
		return (false);
}

