//
// Apply tone-mapping adjustment to a document
// This script is executed by the Image > Adjustements > HDR Toning... menu item
//

$.localize = true;

var g_StackScriptFolderPath = app.path + "/"+ localize("$$$/ScriptingSupport/InstalledScripts=Presets/Scripts") + "/"
										+ localize("$$$/Private/Exposuremerge/StackScriptOnly=Stack Scripts Only/");

$.evalFile(g_StackScriptFolderPath + "StackSupport.jsx");

// These should be added to Terminology.jsx
const eventRasterize               = app.charIDToTypeID('Rstr');
const keyMerge                     = app.charIDToTypeID('Mrge');

const classHistoryState            = app.charIDToTypeID('HstS');
const enumLast                     = app.charIDToTypeID('Lst ');
const keyCurrentHistoryState       = app.charIDToTypeID('CrnH');

// This should be in StackSupport.jsx
function killLastHistoryState()
{
    // Select the last history state
    var selDesc = new ActionDescriptor();
    var selRef = new ActionReference();
    selRef.putEnumerated( classHistoryState, typeOrdinal, enumLast );
    selDesc.putReference( typeNULL, selRef );
    executeAction( eventSelect, selDesc, DialogModes.NO );

    // Nuke it
    var delDesc = new ActionDescriptor();
    var delRef = new ActionReference();
    delRef.putProperty( classHistoryState, keyCurrentHistoryState );
    delDesc.putReference( typeNULL, delRef );
    executeAction( eventDelete, delDesc, DialogModes.NO );
}

// Create a base object to scope the rest of the functions in the file
function ToneAdjuster()
{
	this.pluginName = "HDRToning";
}

toneAdjuster = new ToneAdjuster();

// Version of flatten that'll ask first.  Returns true if it worked.
toneAdjuster.askFlatten = function()
{
	if ((app.activeDocument.layers.length == 1) 
        && (app.activeDocument.activeLayer.isBackgroundLayer))
		return true;	// Already flat

	if (confirm( localize("$$$/HDRToning/ConfirmFlatten=HDR Toning only works on single layered documents.  Do you want to flatten the document?")))
	{
		app.activeDocument.flatten();
		return true;
	}
	return false;
}

toneAdjuster.askRGB = function()
{
    if ((app.activeDocument.mode == DocumentMode.RGB)
        || (app.activeDocument.mode == DocumentMode.GRAYSCALE))
    return true;
    
    if (confirm( localize("$$$/HDRToning/ConfirmRGB=HDR Toning only works in RGB color mode.  Do you want to convert the document to RGB?")))
    {
        app.activeDocument.changeMode( ChangeMode.RGB );
        return true;
    }
    return false;
}


// This should be folded into convertNoDialog in StackSupport.jsx
toneAdjuster.convert32 = function()
{
	if (app.activeDocument.bitsPerChannel == BitsPerChannelType.THIRTYTWO)
		return;

    var desc3 = new ActionDescriptor();
    desc3.putInteger( keyDepth, 32 );
    desc3.putBoolean( keyMerge, true );
    desc3.putBoolean( eventRasterize, false );
	executeAction( eventConvertMode, desc3, DialogModes.NO );
}

toneAdjuster.doAdjustment = function()
{
    var removeHistory = false;
    
    function doConversionNon32()
    {
        toneAdjuster.convert32();	// Make sure it's 32 bit
        try {
            convertFromHDR( resultDepth );
        }
        catch (err)
        {
            undoLastEvent();    // Leave it the depth we found it if canceled
            removeHistory = true;   // Flag state containing this call must go too.
        }
    }

    function doConversion32()
    {
        try {
            convertFromHDR( resultDepth );
        }
        catch (err)
        {
            removeHistory = true;
        }
        toneAdjuster.convert32();   // This is a no-op if the conversion cancelled
    }

	if ((app.documents.length > 0) && this.askFlatten() && this.askRGB())
	{
        var depthMap = {'BitsPerChannelType.EIGHT': 8, 'BitsPerChannelType.SIXTEEN': 16, 'BitsPerChannelType.THIRTYTWO': 16};
        var resultDepth = depthMap[app.activeDocument.bitsPerChannel];
        var was32 = app.activeDocument.bitsPerChannel == BitsPerChannelType.THIRTYTWO;
        // Group the convert to & from into a single operation
        if (was32)
            app.activeDocument.suspendHistory(localize("$$$/HDRToning/HDR Tone State name=HDR Toning"), 
                                                "doConversion32()");
        else
            // Group the convert up to 32 and convert down into a single operation
            app.activeDocument.suspendHistory(localize("$$$/HDRToning/HDR Tone State name=HDR Toning"), 
                                                "doConversionNon32()");

        // If the operation was canceled, remove the history state
        if (removeHistory)
            killLastHistoryState();
    }
}

// Set runtoneadjusterFromScript if you want to load this script w/o running it.
if ((typeof(runtoneadjusterFromScript) == 'undefined')
	|| (runtoneadjusterFromScript==false))
	toneAdjuster.doAdjustment();

