//
//	Copyright (c) 2001 General Electric Company
//
//	Version control:
//		$Archive: /releases/FreeViewer_2.0/src/WebViewer/FreeViewer/HTML/viewfrm.js $
//		$Revision: 24 $
//		$Date: 3/11/03 9:26a $
//		$Author: Marceld $
//
//	Helper comment to enable syntax coloring in InterDev: <script>


var p_dicomdirview = null;
var p_licensekey = null;
var p_bPlayMode = false;
var p_timerID;
var p_bMultiFrameCine;
var p_bStartCineInProgress = false;
var p_bShowAnnotations = true;
var p_nCineSpeed    = 10; // in frames per second.
var s_nCineSpeedMax = 15;
var s_nCineSpeedMin =  1;
var p_rgSeriesAttributes = new Array();
var p_AnnotationContainer = new Object();
var p_ImageUIDs = new Object();
var p_cineattributes = null;
var _bLayoutChanging = false;
var _rgDicomdirSeriesIndex = new Array;

//
// HasErrors
//
function HasErrors()
{
	return (viewlayout.HasErrors() || viewcontrol.HasErrors());
}


//
// GetErrorText
//
function GetErrorText()
{
	if (viewlayout.HasErrors())
		return viewlayout.GetErrorText();

	if (viewcontrol.HasErrors())
		return viewcontrol.GetErrorText();
}


//
// AttachDicomDirView
//
function AttachDicomDirView(IDicomDirView)
{
	// Store the reference to the IDicomDirView interface.
	p_dicomdirview = IDicomDirView;
	
	// Take a subscription on 'change selected image' events.
	p_dicomdirview.onselectionchanged = OnUpdateInNormalMode;
	p_dicomdirview.onnewdicomfilesetloaded = OnNewDicomFileSetLoaded;
	p_dicomdirview.onstudychanged = OnStudyChanged;
	p_dicomdirview.onserieschanged = OnSeriesChanged;

	// Stop the cine if the user goes to the browse dialog.
	p_dicomdirview.onbrowsemode = StopCine;

	p_dicomdirview.SetImagesToHighlight(viewlayout.GetViewportCount());

	// Trigger the first initial update.
	p_dicomdirview.onselectionchanged();
}


//
// SetLicenseKey
//
// Purpose: Receive the license key for the viewport control. 
//          Key is cached to handle viewlayout reloads.
//
function SetLicenseKey(LicenseKey)
{
	p_licensekey = LicenseKey;
	viewlayout.UnlockViewports(p_licensekey);
}

//
// OnSeriesLayoutChange
//
function OnSeriesLayoutChange()
{
	_bLayoutChanging = true;
	if (p_licensekey != null)
	{
		viewlayout.UnlockViewports(p_licensekey);
	}
	if (p_dicomdirview != null)
	{
		var nSeriesIndex = p_dicomdirview.GetActiveSeriesIndex();
		var nImageIndex = p_dicomdirview.GetActiveImageIndex()
		var nSeriesCount = viewlayout._serieslayoutman.GetSeriesCount();
		_rgDicomdirSeriesIndex = new Array(nSeriesCount)
		for (var i = nSeriesCount - 1; i >= 0; i--)
		{
			_rgDicomdirSeriesIndex[i] = nSeriesIndex;
			var oSeries = viewlayout._serieslayoutman.SetActiveSeries(i);
			oSeries.SetSeriesNr(nSeriesIndex);
			oSeries.SetImageNr(nImageIndex);
			p_dicomdirview.SetActiveImages(nSeriesIndex, nImageIndex, viewlayout.GetViewportCount());
		}
	}
	_bLayoutChanging = false;
}


//
// OnLayoutChange
//
// Purpose: Handles the event 'layout change'. This event is sent by
//          the viewlayout when it is (re)loaded.
//
function OnLayoutChange()
{
	_bLayoutChanging = true;
	if (p_licensekey != null)
	{
		viewlayout.UnlockViewports(p_licensekey);
	}
	if (p_dicomdirview != null)
	{
		p_dicomdirview.SetActiveImages(p_dicomdirview.GetActiveSeriesIndex(), p_dicomdirview.GetActiveImageIndex(), viewlayout.GetViewportCount());
	}
	if (p_bStartCineInProgress)
	{
		p_bStartCineInProgress = false;
		StartCine();
	}
	_bLayoutChanging = false;
}


//
// GetActiveSeriesAttributes
//
function GetActiveSeriesAttributes()
{
	var seriesindex = p_dicomdirview.GetActiveSeriesIndex();
	if (seriesindex == -1)
		return null;
	return p_rgSeriesAttributes[seriesindex];
}

//
// OnUpdateInNormalMode
//
function OnUpdateInNormalMode()
{
	// Forward the command to the 'viewlayout' frame.
	viewlayout.UpdateAllViewports(p_dicomdirview, GetActiveSeriesAttributes());

	// Stop the cine if playing.
	if (p_bPlayMode)
	{
		StopCine();
	}

	if (p_dicomdirview.GetActiveSeriesIndex() != -1)
	{
		var oActiveViewport = viewlayout.GetActiveViewport();
		if (oActiveViewport == null)
		{
			viewlayout.SetActiveViewport(0);
		}
		viewlayout.GetActiveViewport().MakeActive();
	}
	viewcontrol.UpdateControls(p_dicomdirview);
	viewcontrol.listWindowPreset.value = viewlayout.GetActiveViewport().GetWindowLevel();
}


//
// OnUpdateInCineControlMode
//
function OnUpdateInCineControlMode()
{
	viewlayout.UpdateAllViewports(p_dicomdirview, p_cineattributes);
}


//
// SetViewportLayout
//
function SetViewportLayout(nRows, nColumns)
{
	viewlayout.SaveImageAnnotations();
	viewlayout.SetViewportLayout(nRows, nColumns);	// change currently selected series area
	OnLayoutChange();
}

//
// SetSeriesLayout
//
function SetSeriesLayout(nRows, nColumns)
{
	if (viewlayout.SetSeriesLayout(nRows, nColumns))
	{
		OnSeriesLayoutChange();
	}
}

//
// ImageBack
//
function ImageBack()
{
	if (viewlayout.IsSelectedImageMultiFrame())
	{
		viewlayout.SelectPreviousFrame();
	}
	else
	{
		p_dicomdirview.SelectPreviousImagesInSeries(1);
	}
}


//
// ImageForward
//
function ImageForward()
{
	if (viewlayout.IsSelectedImageMultiFrame())
	{
		viewlayout.SelectNextFrame();
	}
	else
	{
		p_dicomdirview.SelectNextImagesInSeries(1);
	}
}

//
// PageBack
//
function PageBack()
{
	ASSERT(!viewlayout.IsSelectedImageMultiFrame());
	p_dicomdirview.SelectPreviousImagesInSeries(viewlayout.GetViewportCount());
}

//
// PageForward
//
function PageForward()
{
	ASSERT(!viewlayout.IsSelectedImageMultiFrame());
	p_dicomdirview.SelectNextImagesInSeries(viewlayout.GetViewportCount());
}

//
// SeriesBack
//
function SeriesBack()
{
	p_dicomdirview.SelectPreviousSeries();
}

//
// SeriesForward
//
function SeriesForward()
{
	p_dicomdirview.SelectNextSeries();
}

//
// ImageRewind
//
function ImageRewind()
{
	if (viewlayout.IsSelectedImageMultiFrame())
	{
		viewlayout.SelectFirstImage();
	}
	else
	{
		p_dicomdirview.SelectFirstImageInSeries();
	}
}


//
// ImagePlayStop
//
// Purpose: Toggle the state of the cine: play <-> stop>
//
function ImagePlayStop()
{
	if (p_bPlayMode)
	{
		StopCine();
	}
	else
	{
		if (viewlayout.GetLayout() == "1x1")
		{
			StartCine();
		}
		else
		{
			p_bStartCineInProgress = true;
			SetViewportLayout(1, 1);
		}
	}
}


//
// SetCineSpeed
//
// Purpose: Update the cine speed. It is legal to change the speed while in playmode.
//
function SetCineSpeed(nCineSpeed)
{
	p_nCineSpeed = nCineSpeed;
	if (p_bPlayMode)
	{
		clearInterval(p_timerID);
		p_timerID = setInterval(OnCineTimerTick, 1000 / p_nCineSpeed);
	}
}


//
// GetCineSpeed
//
function GetCineSpeed()
{
	return p_nCineSpeed;
}

//
// CineSpeedChange
//
function CineSpeedChange(nCineSpeed)
{
	SetCineSpeed(nCineSpeed);
	viewcontrol.OnCineSpeedChange(s_nCineSpeedMin, nCineSpeed, s_nCineSpeedMax);
}

//
// CineSpeedDecrease
//
// Purpose: Decrease the cine speed with a stepsize of 1 fps.
//          Lower bound is 1 fps.
//
function CineSpeedDecrease()
{
	var nCineSpeed = GetCineSpeed();
	if (nCineSpeed > s_nCineSpeedMin)
	{
		nCineSpeed -= 1;
		CineSpeedChange(nCineSpeed);
	}
}


//
// CineSpeedIncrease
//
// Purpose: Increase the cine speed with a stepsize of 1 fps.
//          Upper bound is 25 fps.
//
function CineSpeedIncrease()
{
	var nCineSpeed = GetCineSpeed();
	if (nCineSpeed < s_nCineSpeedMax)
	{
		nCineSpeed += 1;
		CineSpeedChange(nCineSpeed);
	}
}


//
// StartCine
// 
function StartCine()
{
	p_bMultiFrameCine = viewlayout.IsSelectedImageMultiFrame();
	p_bPlayMode = true;
	
	// Notify others that a cine is started.
	viewcontrol.NotifyPlayMode(p_bPlayMode);
	viewlayout.NotifyPlayMode(p_bPlayMode);

	p_cineattributes = viewlayout.GetActiveAttributes();
	p_timerID = setInterval(OnCineTimerTick, 1000 / p_nCineSpeed);
}


//
// StopCine
//
function StopCine()
{
	clearInterval(p_timerID);
	p_bPlayMode = false;

	// Notify others that a cine is stopped.
	viewcontrol.NotifyPlayMode(p_bPlayMode);
	viewlayout.NotifyPlayMode(p_bPlayMode);
	p_cineattributes = null;
	p_dicomdirview.onselectionchanged();	// force update
}


//
// OnCineTimerTick
//
// Purpose: Handles timer events by selecting the next image.
//
function OnCineTimerTick()
{
	if (p_bMultiFrameCine)
	{
		viewlayout.SelectNextFrame();
	}
	else
	{
		// Switch to the cine update event handler. The default event handler will stop the cine.
		var OrginalEventHandler = p_dicomdirview.onselectionchanged;
		p_dicomdirview.onselectionchanged = OnUpdateInCineControlMode;

		if (p_dicomdirview.HasNextImageInSeries())
		{
			p_dicomdirview.SelectNextImagesInSeries(1);
		}
		else
		{
			p_dicomdirview.SelectFirstImageInSeries();
		}

		p_dicomdirview.onselectionchanged = OrginalEventHandler;
	}
}


//
// IsSelectedImageMultiFrame
//
function IsSelectedImageMultiFrame()
{
	return viewlayout.IsSelectedImageMultiFrame();
}


//
// SetShowAnnotations
// 
function SetShowAnnotations(bShowAnnotations)
{
	p_bShowAnnotations = bShowAnnotations;
	viewlayout.OnShowAnnotationsChange();
}


//
// GetShowAnnotations
// 
function GetShowAnnotations()
{
	return p_bShowAnnotations;
}


//
// OnMouseWheelViewControl
//
// Purpose: Receives mouse wheel events from the viewport control that has the focus.
//          Normal mode: select the next or previous image in a series.
//          Cine   mode: increase or decrease the cine speed.
//
function OnMouseWheelViewControl(nTicks)
{
	if (nTicks < 0)
	{
		nTicks = Math.abs(nTicks);
		if (p_bPlayMode)
		{
			for (var i = 0; i < nTicks; i++)
			{
				CineSpeedDecrease()
			}
		}
		else
		{
			for (var i = 0; i < nTicks; i++)
			{
				ImageForward()
			}
		}
	}
	else
	{
		if (p_bPlayMode)
		{
			for (var i = 0; i < nTicks; i++)
			{
				CineSpeedIncrease()
			}
		}
		else
		{
			for (var i = 0; i < nTicks; i++)
			{
				ImageBack()
			}
		}
	}
}



//
// ClearSeriesAttributes
//
function ClearSeriesAttributes()
{
	var seriesindex = p_dicomdirview.GetActiveSeriesIndex();
	if (seriesindex == -1)
		return;
	p_rgSeriesAttributes[seriesindex] = null;
}

//
// OnPropagateClicked
//
function OnPropagateClicked()
{
	var seriesindex = p_dicomdirview.GetActiveSeriesIndex();
	if (seriesindex == -1)
		return;

	p_rgSeriesAttributes[seriesindex] = viewlayout.GetActiveAttributes();
	if (viewlayout.GetLayout() != "1x1")
	{
		viewlayout.PropagateAttributes(p_rgSeriesAttributes[seriesindex]);
	}
}


//
// OnNewDicomFileSetLoaded
//
function OnNewDicomFileSetLoaded()
{
	var cnt = p_dicomdirview.GetSeriesCount();
	p_rgSeriesAttributes = new Array(cnt);
	for (var i = 0; i < cnt; i++)
	{
		p_rgSeriesAttributes[i] = null;
	}
	SetSeriesLayout(1, 1);
}


//
// OnStudyChanged
//
function OnStudyChanged()
{
	viewcontrol.ClearPresentationStateListbox();
	viewcontrol.Feed2PresentationStateListbox(GetApp().GetLocaleString('strEmptyPresentationState'), 0);
	// fill dropdown list with presentation states from DICOMDIR
	var cnt = p_dicomdirview.GetPresentationStateCount();
	if (cnt > 0)
	{
		for (var i = 0; i < cnt; i++)
		{
			var str = p_dicomdirview.GetPresentationStateDescription(i);
			if (str == "")
			{
				str = p_dicomdirview.GetPresentationStateLabel(i);
			}
			viewcontrol.Feed2PresentationStateListbox(str, i+1);
		}
	}

	viewcontrol.SelectPresentationState(cnt);
	viewlayout.SelectPresentationState(cnt);
}

//
// OnSeriesChanged
//
function OnSeriesChanged()
{
	viewcontrol.RefreshWLPresetList(p_dicomdirview.GetActiveModality());
}

//
// OnPresentationStateChange
//
function OnPresentationStateChange(value)
{
	ClearImageAnnotations();
	ClearSeriesAttributes();
}

//
// GetPresentationStateIndex
//
function GetPresentationStateIndex()
{
	return viewcontrol.listPresentationStates.value;
}


//
// ClearImageAnnotations
//
function ClearImageAnnotations()
{
	var nSeriesIndex = _rgDicomdirSeriesIndex[viewlayout.GetActiveSeriesIndex()];
	if (nSeriesIndex == -1)
		return;

	p_AnnotationContainer[nSeriesIndex] = new Object();

	p_ImageUIDs = new Object();
}


//
// AddToImageAnnotations
//
function AddToImageAnnotations(seriesindex, uid, strAnnot)
{
	var nSeriesIndex = _rgDicomdirSeriesIndex[seriesindex];
	if (nSeriesIndex == -1)
		return;

	if (p_AnnotationContainer[nSeriesIndex] == null)
	{
		p_AnnotationContainer[nSeriesIndex] = new Object;
	}
	p_AnnotationContainer[nSeriesIndex][uid] = strAnnot;
}


//
// GetImageAnnotation
//
function GetImageAnnotation(seriesindex, uid)
{
	var nSeriesIndex = _rgDicomdirSeriesIndex[seriesindex];
	if (nSeriesIndex == -1)
		return;

	return p_AnnotationContainer[nSeriesIndex] ? p_AnnotationContainer[nSeriesIndex][uid] : null;
}


//
// GetImageUID
//
function GetImageUID(index)
{
	return p_ImageUIDs[index];
}


//
// SetImageUID
//
function SetImageUID(index, uid)
{
	p_ImageUIDs[index] = uid;
}

//
// SetDicomDirActiveImages
//
function SetDicomDirActiveImages(nSeriesIndex, nImageIndex)
{
	p_dicomdirview.SetActiveImages(nSeriesIndex, nImageIndex, viewlayout.GetViewportCount());
}

//
// GetDicomDirImageIndex
//
function GetDicomDirImageIndex()
{
	return p_dicomdirview.GetActiveImageIndex();
}

//
// GetDicomDirSeriesIndex
//
function GetDicomDirSeriesIndex()
{
	return p_dicomdirview.GetActiveSeriesIndex();
}

//
// ChangeWindowLevelPreset
//
function ChangeWindowLevelPreset(strValue)
{
	viewlayout.GetActiveViewport().SetWindowLevel(strValue);
}

//
// IsStaticPaletteMonitor
//
function IsStaticPaletteMonitor()
{
	return viewlayout.GetActiveViewport().IsStaticPaletteMonitor();
}

//
// LayoutHasChanged
//
function LayoutHasChanged()
{
	return _bLayoutChanging;
}

//
// SetSeriesIndex
//
function SetSeriesIndex(seriesidx, dicomdirseriesidx)
{
	_rgDicomdirSeriesIndex[seriesidx] = dicomdirseriesidx;
}
