<?xml version="1.0" ?>
<package>
	<comment>
<![CDATA[
tabs=4
-----------------------------------------------------------------------------------------

ACP Custom User Actions Component Framework (JScript Version)
===========================================

Script:         UserActionsRawWithFITS.wsc
Author:         Robert B. Denny <rdenny@dc3.com>
Version:        8.1
Requires:       ACP 8.1 or later
                Windows Script 5.6 or later (installed by ACP setup)

Environment:    This is a Windows Script Component. Once registered (see below) it
                provides ACP standard scripts with a set of user-written actions that 
                can be performed at several points during the execution of ACP's
                standard scripts.  If you don't have a copy of PrimalScript, I STRONGLY
                suggest you get it and use it to work with this WSC, and ACP scripting
                in general!
                
                http://www.sapien.com/primalscript.aspx
                
Activating:     Normally, ACP does not "see" this component and it's member functions. 
                To activate it for ACP it must be registered with the Windows OS. This
                is simple on 32-bit systems: Right click on UserActions.wsc and select
                Register. If you see a success popup, it's ready to go. If you see a 
                failure popup, there is a mistake in the code or XML.
                
                On 64-bit systems it's a bit more complicated, as UserActions must be
                registered with the 32-bit siubsystem of Windows:
                
                    1. Run C:\Windows\SysWOW64\cmd.exe           <--- Yes, SysWOW64!
                    2. ...> CD "\Program Files\ACP Obs Control"  <-- Note quotes
                    3. ...> regsvr32 UserActions.wsc
                
Usage:          Add your custom script actions to the empty methods below. Access to
                ACP's "Util" object is automatically included. 
                
                To write to the ACP console, call Util.Console.PrintLine(). 
                
                To control the telescope and camera, you MUST use Util.ScriptTelescope 
                and Util.ScriptCamera. DO NOT CREATE INSTANCES OF ACP.TELESCOPE, 
                MAXIM.CCDCAMERA, OR ACP.CAMERA! This will prevent access locks from 
                working properly.
                
                You have access to all global variables in the host ACP script via 
                the Util.Script property. DO NOT CHANGE GLOBALS IN THE HOST SCRIPT,
                as it may cause it to fail.
                
                You have access to all of the facilities in AcquireSupport.wsc. To
                call any of its methods or access any of its properties, use 
                Util.Script.SUP to access the script's global variable that holds the
                object reference to the support library.
                
PLEASE NOTE:    ACP has a built-in facility for running custom scripts at the time it
                it is started up and shutdown. See the ACP helpfile, "Customizing the
                Program" for more info on startup and shutdown scripts.

Edit History:
    23-Nov-06   5.0 Initial edit, after VBScript version of UserActions.wsc 5.0
    17-Jun-07   5.1 TargetStart can now skip targets, see context comments.
    07-Nov-11   No logic change, GEM:732 add notation on registering including for 64 bit
                Remove old startup/shutdown notation.
    28-Apr-16   8.1 - GEM:1458 Add AcquireImage user action.
    23-Feb-17   For AAVSO, save RAW uncalibrated images with full FITS info.
-----------------------------------------------------------------------------------------
]]>
	</comment>
	<component id="UserActions">
		<?component error="false" debug="false" ?>
		<registration progid="ACP.UserActions" classid="{33F9198D-112D-4AB9-8951-F5D7FB5E79AA}" description="ACP custom user action methods" remotable="no" version="1.0">
		</registration>
		<public>
			<method name="ImageComplete">
				<parameter name="ImageFile"/>
			</method>
			<method name="ImageEnd">
				<parameter name="ImageFile"/>
			</method>
			<method name="ImageStart">
				<parameter name="Interval"/>
				<parameter name="Binning"/>
				<parameter name="Subframe"/>
				<parameter name="FilterNum"/>
				<parameter name="ForPointing"/>
			</method>
			<method name="AcquireImage">
				<parameter name="Plan"/>
				<parameter name="Target"/>
				<parameter name="ImageSet"/>
				<parameter name="ImageFile"/>
			</method>
			<method name="ScriptEnd">
			</method>
			<method name="ScriptStart">
			</method>
			<method name="Shutdown">
			</method>
			<method name="SlewEnd">
			</method>
			<method name="SlewStart">
				<parameter name="RightAscension"/>
				<parameter name="Declination"/>
			</method>
			<method name="TargetStart">
				<parameter name="Plan"/>
				<parameter name="Target"/>
				<parameter name="NextTarget"/>
			</method>
			<method name="TargetEnd">
				<parameter name="Plan"/>
				<parameter name="Target"/>
				<parameter name="NextTarget"/>
			</method>
		</public>
		<object id="FSO" progid="Scripting.FileSystemObject" events="false" reference="false"/>
		<object id="ACPApp" progid="ACP.Application" events="false" reference="true"/>
		<object id="Util" progid="ACP.Util" events="false" reference="false"/>
		<script id="UserActions" language="JScript">
<![CDATA[


//------------------------------------------------------------------------------
// ScriptStart()     Called at start of script execution
//
// Parameters:
//   None:
//
// Return True to continue ACP script, False to stop ACP script
//------------------------------------------------------------------------------
function ScriptStart()
{
    Util.Console.PrintLine("** Images will always be calibrated and raw images");
    Util.Console.PrintLine("** will contain full FITS info (for AAVSONet)");
    return true;
}


//------------------------------------------------------------------------------
// ScriptEnd()       Called at the end of script execution
//
// Parameters:
//   None
//
// No return. THIS WILL NOT BE CALLED ON A SCRIPT ERROR
//------------------------------------------------------------------------------
function ScriptEnd()
{
    return;
}


//------------------------------------------------------------------------------
// SlewStart()       Called prior To starting a slew
//
// Parameters:
//   RightAscension:     J2000 right ascension of slew destination
//   Declination:        J2000 declination of slew destination
//
// Return True to permit the slew. False will prevent the slew and cause the 
// script to stop with an error.
//------------------------------------------------------------------------------
function SlewStart(RightAscension, Declination)
{
    return true;
}


//------------------------------------------------------------------------------
// SlewEnd()         Called when a slew has ended
//
// Parameters:
//   None
//
// Return True to permit the script to continue. Returning False will cause the 
// script to stop with an error.
//------------------------------------------------------------------------------
function SlewEnd()
{
    return true;
}


//------------------------------------------------------------------------------
// ImageStart()      Called just before image acquisition
//
// Parameters:
//   Interval:       Exposure interval (sec, 0=bias, neg=dark)   (read/write)
//   Binning:        Binning level                               (read/write)
//   Subframe:       Subframe size (fractional)                  (read/write)
//   FilterNum:      Filter number                               (DO NOT CHANGE!!!!!)
//   ForPointing     True if this is pointing exp.               (DO NOT CHANGE!!!!!)
//
// Return True to permit the script to continue. Returning False will cause the 
// script to stop with an error.
//------------------------------------------------------------------------------
function ImageStart(Interval, Binning, Subframe, FilterNum, ForPointing)
{
    return true;
}


//------------------------------------------------------------------------------
// ImageEnd()        Called when image acquisition has ended
//
// Parameters:
//   ImageFile:      Full path/name to image file
//
// Return True to permit the script to continue. Returning False will cause the 
// script to stop with an error.
//
// NOTE: DO NOT RENAME OR MOVE THE FILE HERE IF YOU ARE USING THIS WITH
//       ACQUIREIMAGES. USE #IMAGECOMPLETE (BELOW), WHICH RUNS AFTER
//       ACQUIREIMAGES IS COMPLETELY FINISHED WITH THE IMAGE FILE (EXCEPT
//       For AUTOSTACKING. SEE NOTE BELOW!)
//------------------------------------------------------------------------------
function ImageEnd(ImageFile)
{
    return true;
}


//------------------------------------------------------------------------------
// Shutdown()        Called by AcquireSupport when its Shutdown method is called
//
// Parameters:
//   None
//
// Return True if you handle observatory shutdown here. If you return False,
// AcquireSupport will run its built-in parking and camera warmup code.
//------------------------------------------------------------------------------
function Shutdown()
{
    return false;                                   // Use built-in shutdown logic
}


//------------------------------------------------------------------------------
// AcquireImage()    Called From AcquireImages.js to acquire an image using 
//                   special logic that completely replaces the acquisition
//                   logic in AcquireImages. Also called from AcquireScheduler
//                   for Scheduler runs. 
//
// Parameters:
//   Plan            ACP.Plan object for currently running plan
//   Target          Current ACP.Target object 
//   ImageSet        Current ACP.ImageSet object
//   ImageFile:      Full path/name to image file
//
// Parameters (Scheduler):
//   Plan            Scheduler Plan object for currently running plan
//   Target          Scheduler Observation object for target
//   ImageSet        Scheduler ImageSet object for this set of images
//   ImageFile:      Full path/name to image file
//
// Environment:
//   The scope is pointing to the target folloowing a pointing update as needed,
//   and any periodic or adaptive autofocus has been done. Nothing else will
//   have been done. If this function does handle the imaging, then it is 
//   responsible for guiding, filter selection, and image acquisition. When
//   it returns, it is assumed that the image file is at the given path (which
//   will be constructed as usual including possible ImageFileConfig customizations. 
//
// Return True to permit the script to continue and acquire an image the normal
// way in AcquireSupport. Returning False will cause the script to stop with 
// an error. Returning the string "ok" will cause the internal AcquireImages
// logic to be skipped, and loop back in the "Count" loop for the next iteration.
//
//------------------------------------------------------------------------------
function AcquireImage(Plan, Target, ImageSet, ImageFile)
{
    return true;
}


//------------------------------------------------------------------------------
// ImageComplete()   Called From AcquireImages.js/~plan-acquire.js when image 
//                   acquisition and processing are complete
//
// Parameters:
//   ImageFile:      Full path/name to image file                (read/write)
//
// Return True to permit the script to continue. Returning False will cause the 
// script to stop with an error. At this point, the image processing is done
// so you may change the image file name.
//
// WARNINGS: 
//   (1) DO NOT CHANGE FILE EXTENSION! IT MUST BE .FTS.
//   (2) IF YOU CHANGE THE FILE NAME, AUTO_STACK WILL BE DISABLED
//------------------------------------------------------------------------------
function ImageComplete(ImageFile)
{
    //
    // Create the RAW subdirectory if needed, copy the file into the RAW
    // subdir, prefixing its name with "RAW-".
    //
    Util.Console.PrintLine("  == Saving uncalibrated image in RAW subfolder ==");
    var rawFldrName = FSO.GetParentFolderName(ImageFile) + "\\RAW";
    if (!FSO.FolderExists(rawFldrName))
        FSO.CreateFolder(rawFldrName);
    var rawFileName = rawFldrName + "\\RAW-" + FSO.GetFileName(ImageFile);
    FSO.CopyFile(ImageFile, rawFileName);
    //
    // Now open the original image and calibrate it. Save as Floating
    // Point to preserve dynamic range that may exceed the original
    // 16-bit fixed-point range due to calibration.
    //
    Util.Console.PrintLine("  == Calibrating image and saving as floating point ==");
    var D = new ActiveXObject("MaxIm.Document");
    D.OpenFile(ImageFile);
    D.Calibrate();
    FSO.DeleteFile(ImageFile);
    D.SaveFile(ImageFile, 3, false, 3, false);      // file, 3=FITS, false=no-autostretch, 3=IEEE floating point)
    
    return true;
}


//------------------------------------------------------------------------------
// TargetStart() Called from AcquireImages.js when a new target is about to 
//               start. Also called from AcquireScheduler for ACP Scheduler runs.
//
// Parameters (ACP):
//   Plan            ACP.Plan object for currently running plan
//   Target          ACP.Target object for target about to be started
//   NextTarget      ACP.Target object for next target, or null
//
// Parameters (Scheduler):
//   Plan            Scheduler Plan object for currently running plan
//   Target          Scheduler Observation object for target about to be started
//   NextTarget      null
//
// Use Util.Script.xxx to access AcquireImages/AcquireScheduler globals, etc.
//
// Return true to permit the target to be acquired by ACP, false will terminate
// the observing run. Return 2 to cause the target to be skipped.
//------------------------------------------------------------------------------
function TargetStart(Plan, Target, NextTarget)
{
    return true;
}


//------------------------------------------------------------------------------
// TargetEnd() Called from AcquireImages.js or AcquireScheduler when the current
//             target's processing is complete.
//
// Parameters(ACP):
//   Plan            ACP.Plan object for currently running plan
//   Target          ACP.Target object for target just completed
//   NextTarget      ACP.Target object for next target, or null
//
// Parameters (Scheduler):
//   Plan            Scheduler Plan object for currently running plan
//   Target          Scheduler Observation object for target about to be started
//   NextTarget      null
//
// Use Util.Script.xxx to access AcquireImages/AcquireScheduler globals, etc.
//
// Return frue to permit the script to continue. Returning false will cause the 
// observing run to terminate.
//------------------------------------------------------------------------------
function TargetEnd(Plan, Target, NextTarget)
{
    return true;
}
]]>
		</script>
	</component>
</package>
