--[[
	This grouping script identifies the properties for AS, CD, CP, DD, LP, LS, VL, XA 
	and similiar modality images which may be either cine or still frames. In
	this version, stills are placed all in one sequence per DICOM series, while
	cine frames are grouped by their source file.
    
	This differs from ultrasound where all stills are placed in a single series.
    
	Allan Noordvyk			19 JAN 2005
     -	Created based on old GroupAS version 
	Allan Noordvyk			16 SEP 2005
     -	Added modality sort for All Images sequence for better handling of CR/RF studies.  
	Allan Noordvyk			29 SEP 2005
     -	Added cine frames to *All Images* sequence at request of Gwinnet, rather
		than just still frames.
	Mahesh Nagarajan		27 JAN 2006
     -	Grouping by filename is a bad idea as when two studies are merged, the images with 
		the same filename are grouped together.
	Mahesh Nagarajan		03 MAY 2006
     -	Improving "All Images" Sequence for Fletcher-Allen
	Mahesh Nagarajan		13 JUN 2006
     -	Multi-frame still images need to be handled better; currently they are treated
		as regular still images which works out badly when a vendor sends more than one 
		multi-frame image in the same series. The easiest solution would be to group
		by image UID if number of frames is greater than 1.
	Mahesh Nagarajan		12 FEB 2007
	-	MAJOR SCRIPT REVAMP; please compare with earlier version on VSS if necessary
	-	Implemented support for user controlled sorting on multiple attributes using prototypes
		from Mike McFarland. For more details on the sequencing engine changes, please consult 
		the document titled "Lua Application Programming Interface for Multiple Sorting 
		Criteria Sequencing. The corresponding FEATs for HRS are FEAT219 and FEAT250.
	-	"All Images" will no longer be created in the sequencing scripts; HRS will take 
		responsibility for generating this sequence
	- 	Modified syntaxes for grouping and sorting hints as part of v11.5 re-write
	Mahesh Nagarajan		17 MAY 2007
	-	Removed the modality prefix and sort suffix from sort names as it looked stupid
	Mahesh Nagarajan		28 MAY 2007
	- 	Bringing back the "All Images" sequence until the corresponding HRS feature gets
		implemented; it has been decided that this sequence will have the option of 
		being sorted on acquisition time or file name.
	-	Modified how still multi-frame images are handled; these should be handled similar to cines
		and not as stills		
	Mahesh Nagarajan		11 FEB 2008
	-	Adding back site-specific code snippets; after a long discussion with Cristian B., it is 
		understood that this code has to stay in the code until proper site files have been installed. Such 
		code is added back but within "dollar sign" demarcations to ensure easy removal at a later date.
	Mahesh Nagarajan		17 MAR 2007	
	-	Noticed a strange sorting problem at Univ. of Wisconsin caused by sorting on image 
	     time only; results in a study acquired partially before midnight to be sorted incorrectly.
	Mahesh Nagarajan		26 MAR 2007
	-	Added an extra group hint for OT images if the META Info version Name tag does not exist
	Shudong Liu			26 MAR 2007
	- Customize the script to split RF images by image UID for  Somerset Community Hospital
	    (REI6692) 
	Shudong Liu  September 11, 2008
	   - Customize the script to sort images by image number for  NORTHWEST IMAGING
	   (CRDB66287)  
	Shudong Liu  November 17, 2008
	   - Customize the script to sort RF images by IMAGE ACQUISITON TIME instead of 
	      image file name. (CRDB68577)
	Shudong Liu  December 22, 2008
	   - Customize the script to split RF images by image UID for BOULDER COMMUNITY HOSPITAL
	    (REI11108) 
	Shudong Liu    Feb. 18, 2009
	- Removed "*All Images*" sequence for HMI 11.6
--]]		

function DeclareTags()
end

function RegisterSortingHintTypes( )
-- ////////////////////////////////////////////////////////////////////////////
-- This function will register the various sort orders that are created for NM
-- ////////////////////////////////////////////////////////////////////////////
    RegisterHintType( "ACQUISITION TIME SORT", "Acquisition Time" )
	RegisterHintType( "IMAGE NUMBER SORT", "Image Number" )
    RegisterHintType( "FILE NAME SORT", "File Name" )	
	RegisterHintType( "ALL IMAGES FILENAME SORT", "File Name" )
	RegisterHintType( "ALL IMAGES ACQ TIME SORT", "Acquisition Time" )
	RegisterHintType( "DEFAULT SORT", "Default" )
end

function Execute()

    DeclareTags()
    
-- ////////////////////////////////////////////////////////////////////////////
-- generates the hints for the sequencer as follows 
-- use SOP instance UID for the multiframe images to generate unique sequences
-- for each multiframe image
-- use FRAME_TYPE_PROP to create and subsequently add all the stills to the same
-- sequence
-- ////////////////////////////////////////////////////////////////////////////

    -- Note that since this is a generic script covering multiple modalities
    -- we do not do a modality sanity check.
	  
	local groupHint01 = GroupingHint:new( ValueForTag( SERIES_DESC_PROP, "?" ) )
    
    -- Regardless of frame type, don't mix images from different series.
    if( HasAttr(SERIES_UID_TAG) ) then
        groupHint01:AddEntry(SERIES_UID_TAG) -- add series uid as primary grouping hint
    end
	
	--$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	-- MaxN: Site hack for Alaska Regional Hospital; splitting all RF images by image UID
	local InstName = GetAttr(INSTITUTION_NAME_TAG)
	
	if ( InstName ~= nil and BestWordMatchInAttr(InstName, "ALASKA REGIONAL", 
	                                                       "Somerset Community Hospital",
														   "BOULDER COMMUNITY HOSPITAL") ) then 
		if ( ValueForTag(MODALITY_PROP) == "RF" ) then
			if( HasAttr(IMAGE_UID_TAG) ) then
				groupHint01:AddEntry(IMAGE_UID_TAG) -- add series uid as primary grouping hint
			end
		end
	end
	--$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
    
    -- Determine frame type
    local sFrameType = ValueForTag( FRAME_TYPE_PROP, "?" )
	-- The image might be a still but still multi-frame
	local nFrames = ValueForTag(NUMBER_OF_FRAMES_TAG)
	local isStillMF = false
	if ( nFrames and nFrames > 1 and sFrameType~="Cine") then
		isStillMF = true
	end	
        
    -- If the frame type is cine
    if( sFrameType == "Cine" or isStillMF == true) then
    
        -- Assign each distinct cine file to its own sequence (probably redundant with series UID, but safe)
        groupHint01:AddEntry(IMAGE_UID_TAG)  
		
		-- For cine clips, no sorting is required as the frames can be assumed to be in the right order. For
		-- safety's sake, we create a dummy sort hint on image UID - unregistered.
		local sortHint01 = SortingHint:new( "Default", "DEFAULT SORT" )
		sortHint01:AddEntry(IMAGE_UID_TAG, true)
		local sortHintSet01 = SortingHintSet:new( )
		sortHintSet01:AddHint( sortHint01, true )
                    
        -- Set as sole grouping hint with no need for sorting (can assume frames in right order)
		AddImage2Sequence( "Cine/Still Sequence", groupHint01, sortHintSet01)  
      
    else -- must be a still

		-- Must check if the still image is multi-frame; if so, it should be split 
		-- into a seperate thumbnail
		local nFrames = ValueForTag(NUMBER_OF_FRAMES_TAG)
		if (nFrames and nFrames > 1) then
			groupHint01:AddEntry(IMAGE_UID_TAG) 
		end
	
		-- MaxN: Note that the default sort for stills is by acquisition time; so we do not
		-- have a seperate "default" sort scheme like we did for CT & MR. 
		local sortHint01 = SortingHint:new( "Acquisition Time", "ACQUISITION TIME SORT" )
		
        sortHint01:AddEntry(ACQUISITON_DATETIME_TAG)
        sortHint01:AddEntry(ACQUISITON_DATE_TAG)
        sortHint01:AddEntry(ACQUISITON_TIME_TAG)
        sortHint01:AddEntry(IMAGE_ACQUISITION_DATE_TAG)  
        sortHint01:AddEntry(IMAGE_ACQUISITON_TIME_TAG)   
        sortHint01:AddEntry(INSTANCE_NUMBER_TAG)   
        sortHint01:AddEntry(ALI_IMAGE_FILENAME_TAG)
        sortHint01:AddEntry(IMAGE_UID_TAG)
		
		-- Create a "Sort Hint Set" here; all alternate sorts will be added to this one if they are created
		local sortHintSet01 = SortingHintSet:new( )
		sortHintSet01:AddHint( sortHint01, true )		
		
		-- Creating an image number sort for Cine - created only if (0020, 0013) REL Image Number exists
		if (HasAttr(INSTANCE_NUMBER_TAG)) then
			local sortHint02 = SortingHint:new( "Image Number", "IMAGE NUMBER SORT" )
			sortHint02:AddEntry( INSTANCE_NUMBER_TAG, true ) 
		
			-- If we are here, then the image number sort was created successfully; adding it to the sort hint set for cine
			--$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
			if ( InstName ~= nil and BestWordMatchInAttr(InstName, "NORTHWEST IMAGING") ) then 
				sortHintSet01:AddHint( sortHint02, true )
			--$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
			else 
				sortHintSet01:AddHint( sortHint02 )
			end	
		end
    
		-- Not checking for file name as it should always exist
		local sortHint03 = SortingHint:new( "File Name", "FILE NAME SORT" )
		sortHint03:AddEntry( ALI_IMAGE_FILENAME_TAG, true )
		sortHintSet01:AddHint( sortHint03 )
	
        AddImage2Sequence( "Cine/Still Sequence", groupHint01, sortHintSet01 )
    end
    
end

