context: #region License
  
  // Copyright (c) 2013, ClearCanvas Inc.
  // All rights reserved.
  // http://www.clearcanvas.ca
  //
  // This file is part of the ClearCanvas RIS/PACS open source project.
  //
  // The ClearCanvas RIS/PACS open source project is free software: you can
  // redistribute it and/or modify it under the terms of the GNU General Public
  // License as published by the Free Software Foundation, either version 3 of the
  // License, or (at your option) any later version.
  //
  // The ClearCanvas RIS/PACS open source project is distributed in the hope that it
  // will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  // Public License for more details.
  //
  // You should have received a copy of the GNU General Public License along with
  // the ClearCanvas RIS/PACS open source project.  If not, see
  // <http://www.gnu.org/licenses/>.
  
  #endregion
  
  using System;
  using System.Collections;
  using System.Linq;
  using System.Security.Permissions;
  using System.ServiceModel;
  using System.Text;
  using System.Threading;
  using System.Collections.Generic;
  using ClearCanvas.Common;
  using ClearCanvas.Common.Utilities;
  using ClearCanvas.Desktop;
  using ClearCanvas.Desktop.Validation;
  using ClearCanvas.Enterprise.Common;
  using ClearCanvas.Ris.Application.Common;
  using ClearCanvas.Ris.Application.Common.ReportingWorkflow;
  using ClearCanvas.Ris.Client.Formatting;
  using ClearCanvas.Ris.Application.Common.Admin.StaffAdmin;
  
  namespace ClearCanvas.Ris.Client.Workflow
  {
  	/// <summary>
  	/// Defines an interface for providing custom pages to be displayed in the reporting component.
  	/// </summary>
  	public interface IReportingPageProvider : IExtensionPageProvider<IReportingPage, IReportingContext>
  	{
  	}
  
  	/// <summary>
  	/// Defines an interface to a custom reporting page.
  	/// </summary>
  	public interface IReportingPage : IExtensionPage
  	{
  	}
  
  	/// <summary>
  	/// Defines an interface for providing a custom page with access to the reporting context.
  	/// </summary>
  	public interface IReportingContext
  	{
  		/// <summary>
  		/// Gets the reporting worklist item.
  		/// </summary>
  		ReportingWorklistItemSummary WorklistItem { get; }
  
  		/// <summary>
  		/// Occurs to indicate that the <see cref="WorklistItem"/> property has changed,
  		/// meaning the entire reporting context is now focused on a different report.
  		/// </summary>
  		event EventHandler WorklistItemChanged;
  
  		/// <summary>
  		/// Gets the report associated with the worklist item.  Modifications made to this object
  		/// will not be persisted.
  		/// </summary>
  		ReportDetail Report { get; }
  
  		/// <summary>
  		/// Gets the index of the active report part (the part that is being edited).
  		/// </summary>
  		int ActiveReportPartIndex { get; }
  
  		/// <summary>
  		/// Gets the order detail associated with the report.
  		/// </summary>
  		OrderDetail Order { get; }
  	}
  
  	public interface IReportEditorContextBase<TCloseReason> : IReportingContext
  	{
  		/// <summary>
  		/// Gets a value indicating the active report part is an addendum.
  		/// </summary>
  		bool IsAddendum { get; }
  
  		/// <summary>
  		/// Gets or sets the report content for the active report part.
  		/// </summary>
  		string ReportContent { get; set; }
  
  		/// <summary>
  		/// Gets or sets the extended properties for the active report part.
  		/// </summary>
  		Dictionary<string, string> ExtendedProperties { get; set; }
  
  		/// <summary>
  		/// Gets the specified extended property for the active report part.
  		/// </summary>
  		string GetReportPartExtendedProperty(string key);
  
  		/// <summary>
  		/// Sets the specified extended property for the active report part.
  		/// </summary>
  		void SetReportPartExtendedProperty(string key, string value);
  
  		/// <summary>
  		/// Allows the report editor to request that the reporting component close.
  		/// For example, the report editor may wish to have a microphone button initiate the 'Verify' action.
  		/// </summary>
  		/// <param name="reason"></param>
  		void RequestClose(TCloseReason reason);
  	}
  
  	public interface IReportEditorBase<TCloseReason>
  	{
  		/// <summary>
  		/// Gets the report editor application component.
  		/// </summary>
  		/// <returns></returns>
  		IApplicationComponent GetComponent();
  
  		/// <summary>
  		/// Instructs the report editor to save the report content and any other data.
  		/// The report editor may be veto the action by returning false.
  		/// </summary>
  		/// <param name="reason"></param>
  		/// <returns>True to continue with save, or false to veto the operation.</returns>
  		bool Save(TCloseReason reason);
  	}
  
  	/// <summary>
  	/// Defines an extension point for adding custom pages to the reporting component.
  	/// </summary>
  	[ExtensionPoint]
  	public class ReportingPageProviderExtensionPoint : ExtensionPoint<IReportingPageProvider>
  	{
  	}
  
  	/// <summary>
  	/// Defines an interface for providing a custom report editor.
  	/// </summary>
  	public interface IReportEditorProvider
  	{
  		IReportEditor GetEditor(IReportEditorContext context);
  	}
  
  	/// <summary>
  	/// Defines an interface for providing a custom report editor page with access to the reporting
  	/// context.
  	/// </summary>
  	public interface IReportEditorContext : IReportEditorContextBase<ReportEditorCloseReason>
  	{
  		/// <summary>
  		/// Gets a value indicating whether the Verify operation is enabled.
  		/// </summary>
  		bool CanVerify { get; }
  
  		/// <summary>
  		/// Gets a value indicating whether the Submit For Review operation is enabled.
  		/// </summary>
  		bool CanSubmitForReview { get; }
  
  		/// <summary>
  		/// Gets a value indicating whether the Send To Transcription operation is enabled.
  		/// </summary>
  		bool CanSendToTranscription { get; }
  
  		/// <summary>
  		/// Gets the supervisor for the active report part.
  		/// </summary>
  		StaffSummary Supervisor { get; }
  
  		/// <summary>
  		/// Raises or lowers the order priority by the specified amount.
  		/// </summary>
  		/// <param name="delta"></param>
  		/// <remarks>
  		/// Attempting to raise the priority above the maximum value, or lower it below the minimum value, has no effect. Specifying a delta of 0 will cause the priority to cycle to the next valid value.
  		/// </remarks>
  		void ChangePriority(int delta);
  
  	}
  
  	/// <summary>
  	/// Defines possible reasons that the report editor is closing.
  	/// </summary>
  	public enum ReportEditorCloseReason
  	{
  		/// <summary>
  		/// User has cancelled editing, leaving the report in its current state.
  		/// </summary>
  		CancelEditing,
  
  		/// <summary>
  		/// Report is saved in its current state.
  		/// </summary>
  		SaveDraft,
  
  		/// <summary>
  		/// Report is saved for transcription.
  		/// </summary>
  		SendToTranscription,
  
  		/// <summary>
  		/// Report is saved and send back to the interpreter.
  		/// </summary>
  		ReturnToInterpreter,
  
  		/// <summary>
  		/// Report is saved and submitted for another radiologist to review.
  		/// </summary>
  		SubmitForReview,
  
  		/// <summary>
  		/// Report is saved and verified immediately.
  		/// </summary>
  		Verify
  	}
  
  	public interface IReportEditor : IReportEditorBase<ReportEditorCloseReason>
  	{
  	}
  
  	/// <summary>
  	/// Defines an extension point for providing a custom report editor.
  	/// </summary>
  	[ExtensionPoint]
  	public class ReportEditorProviderExtensionPoint : ExtensionPoint<IReportEditorProvider>
  	{
  	}
  
  	/// <summary>
  	/// Extension point for views onto <see cref="ReportingComponent"/>
  	/// </summary>
  	[ExtensionPoint]
  	public class ReportingComponentViewExtensionPoint : ExtensionPoint<IApplicationComponentView>
  	{
  	}
  
  	/// <summary>
  	/// ReportingComponent class
  	/// </summary>
  	[AssociateView(typeof(ReportingComponentViewExtensionPoint))]
  	public class ReportingComponent : ApplicationComponent
  	{
  		private class UserSkippedItemWithIncompleteDocumentationException : Exception
  		{
  		}
  
  		#region ReportingContext
  
  		class ReportingContext : IReportingContext
  		{
  			private readonly ReportingComponent _owner;
  
  			public ReportingContext(ReportingComponent owner)
  			{
  				_owner = owner;
  			}
  
  			public ReportingWorklistItemSummary WorklistItem
  			{
  				get { return _owner.WorklistItem; }
  			}
  
  			public event EventHandler WorklistItemChanged
  			{
  				add { _owner._worklistItemChanged += value; }
  				remove { _owner._worklistItemChanged -= value; }
  			}
  
  			public ReportDetail Report
  			{
  				get { return _owner._report; }
  			}
  
  			public int ActiveReportPartIndex
  			{
  				get { return _owner._activeReportPartIndex; }
  			}
  
  			public OrderDetail Order
  			{
  				get { return _owner._orderDetail; }
  			}
  
  			protected ReportingComponent Owner
  			{
  				get { return _owner; }
  			}
  		}
  
  		#endregion
  
  		#region ReportEditorContext
  
  		class ReportEditorContext : ReportingContext, IReportEditorContext
  		{
  			public ReportEditorContext(ReportingComponent owner)
  				: base(owner)
  			{
  			}
  
  			public bool CanVerify
  			{
  
gt: 				get { return Owner.CanVerify; }