(* components.sml *)

(* Components: defines a function make to write a Component description
 * file, and a function make_fg to write a File Group file.
*)

signature COMPONENTS =
sig
  val make: (string * string * string) list * string -> unit
    (* write out a component description file *)
  val make_fg: string list * string -> unit
    (* write out a File Group description file (e.g. cml.flg) *)
end

structure Components : COMPONENTS =
struct

  val default_cdf_sects = 
    [
     {name = "Info",
      bindings = [
                  {name = "Type" , value = "CompDef"},
                  {name = "Version" , value = "2.10.000"},
                  {name = "Name" , value = ""}
                  ]},
     {name = "SetupType",
      bindings = [
                  {name = "setuptype0" , value = "Compact"},
                  {name = "setuptype1" , value = "Typical"},
                  {name = "setuptype2" , value = "Custom"}
                  ]},
     {name = "SetupTypeItem-Compact",
      bindings = [
                  {name = "Comment" , value = ""},
                  {name = "item0" , value = "runtime"},
                  {name = "item1" , value = "compiler"},
                  {name = "Descrip" , value = "This setup type only installs the runtime system and the compiler. "},
                  {name = "DisplayText" , value = ""}
                  ]},
     {name = "SetupTypeItem-Custom",
      bindings = [
                  {name = "Comment" , value = ""},
                  {name = "Descrip" , value = "This setup type allows you to choose the components to install. "},
                  {name = "DisplayText" , value = ""}
                  ]}]
    
  fun mapI f l =
      let fun iterMapI f [] i = []
	    | iterMapI f (x::xs) i = (f (x,i))::(iterMapI f xs (i+1))
       in iterMapI f l 0
      end

  (* in IS6.2, TARGET is replaced by DESTINATION, and INSTALLATION
   * by OVERWRITE, and these properties are associated with File Groups
   * rather than Components. *)

  fun make_component (name,descr,status) = 
      {name = name,
       bindings = 
        [{name = "OBJECT" , value = "No"},
	 {name = "DESCRIPTION" , value = descr},
	 {name = "STATUS" , value = status},
	 {name = "VISIBLE" , value = "Yes"},
	 {name = "DISK" , value = "ANYDISK"},
	 {name = "FILENEED" , value = "STANDARD"},
	 {name = "INCLUDEINBUILD" , value = "Yes"},
	 {name = "PASSWORD" , value = ""},
	 {name = "ENCRYPT" , value = "No"},
	 {name = "COMPRESSIFSEPARATE" , value = "No"},
	 {name = "UNINSTALLABLE" , value = "Yes"},
	 {name = "COMMENT" , value = ""},
	 {name = "DEFSELECTION" , value = "Yes"},
	 {name = "SELECTED" , value = "Yes"},
	 {name = "IMAGE" , value = ""},
	 {name = "TARGETDIRCDROM" , value = ""},
	 {name = "DISPLAYTEXT" , value = ""},
	 {name = "HTTPLOCATION" , value = ""},
	 {name = "FTPLOCATION" , value = ""},
	 {name = "MISC" , value = ""},
	 {name = "GUID" , value = ""},
	 {name = "_SPLIT_BEFORE" , value = ""},
	 {name = "_SPLIT_AFTER" , value = ""},
	 {name = "_DATAASFILES" , value = ""},
	 {name = "_NO_SPLIT" , value = ""},
	 {name = "_NO_SPLIT_BEFORE" , value = ""},
	 {name = "VOLATILE" , value = ""},
	 {name = "filegroup0" , value = name},
	 {name = "HANDLERONInstalling" , value = ""},
	 {name = "HANDLERONInstalled" , value = ""},
	 {name = "HANDLERONUnInstalling" , value = ""},
	 {name = "HANDLERONUnInstalled" , value = ""}]}
		   
   (* {name = "TARGET" , value = "<TARGETDIR>"},  5.5 *)
   (* {name = "INSTALLATION" , value = "ALWAYSOVERWRITE"}, 5.5 *)
   (* {name = "TARGETHIDDEN" , value = "General Application Destination"} *)

    
  fun make (list,out_file) =
      let val comp_list = 
              mapI (fn ((s,_,_),i) => {name="component"^(Int.toString i), value=s})
	           list
	  val item_list =
              mapI (fn ((s,_,_),i) => {name="item"^(Int.toString i), value=s})
	           list
	  val comp_section = {name = "Components",bindings = comp_list}
	  val top_section = {name = "TopComponents",bindings= comp_list}
	  val components = map make_component list
	  val typical_section =
	      {name = "SetupTypeItem-Typical",
	       bindings = [{name = "Comment" , value = ""},
			   {name = "Descrip" , value = "This setup type installs the runtime system, the compiler, and all the associated tools. This is the recommended setup."},
			   {name = "DisplayText" , value = ""}]@item_list}
	  val file = {sections = comp_section::top_section::typical_section::
		                 (default_cdf_sects@components)}
       in Verbose.message ["Creating ",out_file];
	  IniFile.write (out_file,file)
      end

  fun make_fg (list,filePath) =
      let val info_sect =
	      {name = "Info",
	       bindings =
                 [{name = "Name" , value = ""},
		  {name = "Type" , value = "FileGrp"},
		  {name = "Version" , value = "2.10.000"}]}
	  val fg_sect = 
	      {name = "FileGroups",
	       bindings = mapI (fn (s,i) => {name = "group"^(Int.toString i),
					     value = s})
	                       list}
	  fun make_sect (s) =
	      {name = s,
	       bindings =
                 [{name = "LINKTYPE",        value = "Static Link"},
		  {name = "INFOTYPE",        value = "Standard"},
		  {name = "UNINSTALLABLE",   value = "Yes"},
		  {name = "FILETYPE",        value = "No"},
		  {name = "SELFREGISTERING", value = "No"},
		  {name = "POTENTIALLY",     value = "No"},
		  {name = "COMPRESS",        value = "Yes"},
		  {name = "OPERATINGSYSTEM", value = ""},
		  {name = "LANGUAGE",        value = ""},
		  {name = "COMMENT",         value = ""},
		  {name = "COMPRESSDLL",     value = ""},
		  {name = "HTTPLOCATION",    value = ""},
		  {name = "FTPLOCATION",     value = ""},
		  {name = "MISC",            value = ""},
		  {name = "INSTALLATION",    value = "ALWAYSOVERWRITE"},
		  {name = "TARGET",          value = "<TARGETDIR>"},
		  {name = "TARGETHIDDEN",    value = "General Application Destination"}]}
(*
		  {name = "OVERWRITE",       value = "Always"},     (* 6.2? *)
		  {name = "DESTINATION",     value = "<TARGETDIR>"} (* 6.2? *)
*)
	  val fg_sects = map make_sect list
	  val file = {sections = info_sect::fg_sect::fg_sects}
       in Verbose.message ["Creating ",filePath];
	  IniFile.write (filePath,file)
      end

end  (* structure Components *)
