{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}

unit templatesystem;

interface

Type
 TTemplateInformation = Record
  CreationDate: String;
  Creator: String;
  Email: String;
  ScreenName: string;
  CMLType: String;
 end;
 TTemplateRequired = Record
  Visuals: String;
  Generals: String;
 end;
 TTemplate = Record
  Information: TTemplateInformation;
  Required: TTemplateRequired;
  ActualCML: String;
  Filename: String;
 end;
 TTemplateList = Class(TObject)
 private
  fList: Array of TTemplate;
  fFolder: String;
  function GETCOUNT: Integer;
  function GETTEMPLATE(Index: Integer): TTemplate;
  procedure SETTEMPLATE(Index: Integer; const Value: TTemplate);
 public
  Property Count: Integer read GETCOUNT;
  Property Template[Index: Integer]: TTemplate read GETTEMPLATE write SETTEMPLATE; default;
  Property Folder: String read fFolder write fFolder;
  Procedure Delete(Index: Integer);
  Function Add: Integer; overload;
  Procedure Add(Filename: String); overload;
  Procedure SaveToFolder(Folder: String);
  Procedure LoadFromFolder(Folder: String);
 end;

implementation

Uses Sysutils, Dialogs, Classes, Filter, lpl_sysutils,
      Forms, xmldom, XMLIntf, XMLDoc, msxmldom;

{ TTemplateList }

function TTemplateList.Add: Integer;
begin
 setlength(fList, count + 1);
 Result := Count-1;
end;

procedure TTemplateList.Add(Filename: String);
Var
 Form: TForm;
 XML: TXMLDocument;
 Temp: TTemplate;
 root: IXMLNode;
 Information: IXMLNode;
 Required: IXMLNode;
 I: Integer;
 List: TStringlist;
begin
 Temp.Filename := extractfilename(Filename);
 Form := TForm.Create(nil);
 XML := TXMLDocument.Create(form);
 XML.LoadFromFile(Filename);
 Try
  XML.Active := true;
 except
  FreeAndNil(XML);
  FreeAndNil(Form);
  Exit;
 end;
 Root := XML.ChildNodes[0];
 If root <> nil then begin
  Information := Root.ChildNodes['Information'];
  If Information <> nil then begin
   Try
    Temp.Information.Creator := Information.Attributes['creator'];
   except
   end;
   Try
    Temp.Information.Email := Information.Attributes['email'];
   except
   end;
   Try
    Temp.Information.CreationDate := Information.Attributes['creationdate'];
   except
   end;
   Try
    Temp.Information.ScreenName := Information.Attributes['screenname'];
   except
   end;
   Try
    Temp.Information.CMLType := Information.Attributes['cmltype'];
   except
   end;
  end;
  Temp.Required.Visuals := '';
  Temp.Required.Generals := '';
  Required := Root.ChildNodes['Required'];
  If required <> nil then begin
   For I := 0 to required.ChildNodes.Count - 1 do begin
    If uppercase(required.ChildNodes[I].NodeName) = 'GENERAL' then begin
     Temp.Required.Generals := Temp.Required.Generals + '|' + required.ChildNodes[I].Attributes['guid']; 
    end;
    If uppercase(required.ChildNodes[I].NodeName) = 'VISUAL' then begin
     Temp.Required.Visuals := Temp.Required.Visuals + '|' + required.ChildNodes[I].Attributes['guid'];
    end;
   end;
  end;
  Temp.Required.Visuals := Copy(Temp.Required.Visuals, 2, length(Temp.Required.Visuals));
  Temp.Required.Generals := Copy(Temp.Required.Generals, 2, Length(Temp.Required.Generals));
  XML.Active := false;
  List := TStringList.Create;
  List.LoadFromFile(filename);
  While uppercase(List[0]) <> '  <ACTUALCML>' do begin
   List.Delete(0);
  end;
  While uppercase(List[List.Count-1]) <> '  </ACTUALCML>' do begin
   List.Delete(List.Count-1);
  end;
  // the next 2 will delete the <actualcml> tags
  List.Delete(0);
  List.Delete(List.count-1);
  Temp.ActualCML := List.Text;
  SetLength(fList, count + 1);
  fList[Count-1] := Temp;
  FreeAndNil(List);
 end;
 FreeAndNil(XML);
 FreeAndNil(Form);
end;

procedure TTemplateList.Delete(Index: Integer);
Var
 I: Integer;
begin
 If fileexists(PathToOk(Folder) + fList[Index].Filename) then begin
  DeleteFile(PathToOk(Folder) + fList[Index].Filename);
 end;
 For I := Index to Count - 2 do begin
  fList[I] := fList[I + 1];
 end;
 SetLength(fList, count - 1);
end;

function TTemplateList.GETCOUNT: Integer;
begin
 Result := length(flist);
end;

function TTemplateList.GETTEMPLATE(Index: Integer): TTemplate;
begin
 Result := fList[Index];
end;

procedure TTemplateList.LoadFromFolder(Folder: String);
Var
 SR: TSearchRec;
begin
 If FindFirst(PathToOk(Folder) + '*.xml', faArchive, SR) = 0 then begin
  repeat
   if uppercase(copy(SR.Name, 1, length('template_form_'))) = 'TEMPLATE_FORM_' then begin
    Add(PathToOk(Folder) + SR.Name);
   end;
   if uppercase(copy(SR.Name, 1, length('template_visual_'))) = 'TEMPLATE_VISUAL_' then begin
    Add(PathToOk(Folder) + SR.Name);
   end;
   if uppercase(copy(SR.Name, 1, length('template_sensor_'))) = 'TEMPLATE_SENSOR_' then begin
    Add(PathToOk(Folder) + SR.Name);
   end;
  until FindNext(SR) <> 0;
  FindClose(SR);
 end;
end;

procedure TTemplateList.SaveToFolder(Folder: String);
Var
 List: TStringList;
 I, II: Integer;
begin
 if not directoryexists(folder) then begin
  If not ForceDirectories(folder) then begin
   MessageDlg('Unable to create the template directory'+#13+#10+'Folder: ' + Folder, mtError, [mbOK], 0);
   exit;
  end;
 end;
 List := TStringList.Create;
 For I := 0 to count - 1 do begin
  List.Clear;
  If fList[I].Filename = '' then begin
   fList[I].Filename := 'template_' + fList[I].Information.CMLType + '_' + fList[I].Information.ScreenName + '.xml';
  end;
  List.Add('<OutlawEdReposFile>');
  List.Add('  <Information creator="' + fList[I].Information.Creator +
                           '" email="' + fList[I].Information.Email +
                           '" screenname="' + fList[I].Information.ScreenName +
                           '" creationdate="' + fList[I].Information.CreationDate +
                           '" cmltype="' + fList[I].Information.CMLType + '"/>');
  List.Add('  <Required>');
  For II := 1 to CountFilt(fList[I].Required.Visuals, '|') do begin
   List.Add('    <Visual guid="' + GetFilt(fList[I].Required.Visuals, II, '|') + '"/>')
  end;
  For II := 1 to CountFilt(fList[I].Required.Generals, '|') do begin
   List.Add('    <General guid="' + GetFilt(fList[I].Required.Generals, II, '|') + '"/>')
  end;
  List.Add('  </Required>');
  List.Add('  <ActualCML>');
  List.Add(fList[I].ActualCML);
  List.Add('  </ActualCML>');
  List.Add('</OutlawEdReposFile>');
  List.SaveToFile(PathToOk(Folder) + fList[I].Filename);
 end;
end;

procedure TTemplateList.SETTEMPLATE(Index: Integer;
  const Value: TTemplate);
begin
 fList[Index] := Value;
end;

end.
