with Ada.Calendar;
with Libsens.Common;                    use Libsens.Common;

with Libsens.Virtual.Plugins;
package Libsens.Virtual.Work_Class is
   
   
   
   
   type Categories_Access is access Categories_Record;
   
   type Breaks_Set_Access is access Breaks_Set_Type;
   
   type Work_Options_Record is tagged
      record
	 Track_Length : Positive := 129;
	 Tempo      : Tempo_Type := 120.0;
	 Signature  : Time_Signature_Type := (4, 4);	    
	 In_Loop    : Boolean := False;	 
	 Current_Form : Form_Index_Type := 1;
	 Current_Break    : Break_Type := Down_Break;
	 Prev_Break       : Break_Type := Null_Break;	 
	 Next_Break       : Break_Type := Down_Break;
	 Forms_Names    : Forms_Names_Set_Type := Forms_Names_Set;
	 Categories      : Categories_Access := new Categories_Record ' (16, Categories_Default, 16);
	 Breaks_Set : Breaks_Set_Access := new Breaks_Set_Type ' (Null_Break, Down_Break,
								  Up_Break, Full_Break,
								  Down_Break, Null_Break,
								  Up_Break, Null_Break,								  
								  Full_Break, Full_Break,
								  Down_Break, Null_Break,
								  Full_Break, Down_Break);
	 True_Table : True_Table_Type;
	 
	 Filename : access String := new String ' ("");
	 
      end record;
   
   type Work_Options_Access is access all Work_Options_Record;
   
   use Libsens.Virtual.Plugins;
      
   type Abstract_Plugin_Access is access all Plugin_Class'class;
   
   function Initialize(Class : in Plugin_Enum;
		       Id        : in Plugin_num;
		       Device    : in Device_Num;
		       Ch        : in Channel_Num;
		       Form      : in Form_Index_Type;
		       Cat       : in Category_Index_Type)          
		      return Abstract_Plugin_Access;
   
   procedure Print (Filename : in String; Plugin : in Abstract_Plugin_Access);      
   
   type Plugin_Set is array (Plugin_num'range) of Abstract_Plugin_Access;      
   
   type Work_Num is new Positive range 1..128;
   
   type States_Record is tagged
      record
	 Start_Time : Ada.Calendar.Time := Ada.Calendar.Clock;	 
	 Bar_Beat : Bar_Beat_Type := (1, 1, 1);
	 Elapsed    : Duration := 0.0;
      end record;
   
   type Work_Record is tagged
      record
	 
	 Id      : Work_Num := 1;	 
	 Started : Boolean := False;	 	 
	 Filename : access String := new String ' ("");
	 
	 Options    : aliased Work_Options_Record;
	 Plugins    : Plugin_Set;
	 
	 States     : States_Record;
      end record;
   
   procedure Initialize(Work : in out Work_Record;
			Work_Id : in Work_Num;
			Filename : in String);
   
   procedure Save(Work : in out Work_Record'Class;
		  Filename : in String := "");
   
   
   
   procedure Finalize(Work : in out Work_Record);
   
   function Get_Plugin(Work : in Work_Record;
		       Plugin_Id : in Plugin_Num)
		      return Abstract_Plugin_Access;
   
   type Work_Access is access all Work_Record'class;      
   
   type Work_Array is array (Work_Num'Range) of Work_Access;      
   
end Libsens.Virtual.Work_Class;