unit ZCubeExplr_SRC;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,ComObj, Grids, ExtCtrls,DateUtils,zCube_TLB, ComCtrls,db,
  zCubeExplorer_TLB, Menus,IniFiles,ColorsForm_SRC, FontsForm_SRC,
  ImgList, OleServer, StdVcl, AxCtrls,dbtables,CubedefForm_SRC;


type
  TzExplorerForm = class(TForm)
    MainMenu1: TMainMenu;
    Cube1 : TMenuItem;
    Settings1: TMenuItem;
    Color1: TMenuItem;
    Fonts1: TMenuItem;
    ODialog: TOpenDialog;
    Sdialog: TSaveDialog;
    Splitter1: TSplitter;
    PrintItem: TMenuItem;
    Windows1: TMenuItem;
    Cascade1: TMenuItem;
    ile1: TMenuItem;
    ArrangeIcons1: TMenuItem;
    Load1: TMenuItem;
    Save1: TMenuItem;
    N2: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure New1Click(Sender: TObject);
    procedure Loadstructure1Click(Sender: TObject);
    procedure SaveClick(Sender: TObject);
    procedure Color1Click(Sender: TObject);
    procedure Fonts1Click(Sender: TObject);
    procedure PrintItemClick(Sender: TObject);
    procedure Exit2Click(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Cascade1Click(Sender: TObject);
    procedure ile1Click(Sender: TObject);
    procedure ArrangeIcons1Click(Sender: TObject);
    procedure Load1Click(Sender: TObject);
    procedure Save1Click(Sender: TObject);
  private
    { Private declarations }
   FCube : ICube;
   Monitor : ILoadMonitor;
   procedure HistoryCLick(Sender : TObject);
   procedure LoadStructure(FileName : string);
  public
    { Public declarations }
    CubeDef : TCubeDef;
    GridSettings : TGridSettings;
    procedure BuildCube;
    function ProcessSQL(Alias,SQL : string) : string;
  end;

var
  zExplorerForm: TzExplorerForm;

implementation

uses BoundForm_SRC,MapForm_SRC,LoadCubeForm_SRC;

{$R *.dfm}

procedure TzExplorerForm.FormCreate(Sender: TObject);
var
   ini : TIniFile;
   i : integer;
   s : string;
   m : TMenuItem;
   fs : TStream;
begin
//FCubeCount := 0;
GridSettings := TGridSettings.Create;
fs := TSTream.Create;

try
   ReadComponentResFile('zCubeExplr.zrc',GridSettings);
   except
         MessageDlg('Could not read colors and font settings for grid',mtWarning,[mbOk],0);
   end;

ini := TIniFile.Create('zCubeExplorer.ini');


i := 1;
repeat
      s := ini.ReadString('HISTORY',IntToStr(i),'');
      if s <> '' then
         begin
         if i = 1 then
            begin
            m := TMenuItem.Create(Self);
            m.Caption := '-';
            Cube1.Add(m);
            end;
         m := TMenuItem.Create(Self);
         m.Caption := s;
         m.OnClick := HistoryClick;
         Cube1.Add(m);
         end;
      inc(i);
      until s = '';
ini.Free;
end;

procedure TzExplorerForm.FormDestroy(Sender: TObject);
var
   ini : TIniFile;
   s : string;
   sl : TStringList;
   i : integer;
   fs : TMemoryStream;
begin
ini := TIniFile.Create('zCubeExplorer.ini');

if ODialog.FileName <> '' then
   begin
   sl := TStringList.Create;
   sl.Duplicates := dupIgnore;
   sl.CaseSensitive := False;
   i := 1;
   while True do
         begin
         s := ini.ReadString('HISTORY',IntToStr(i),'');
         if s <> '' then
            sl.Add(s)
         else
            Break;
         Inc(i);
         end;
   ini.EraseSection('HISTORY');
   ini.UpdateFile;
   sl.Insert(0,ODialog.FileName);
   if sl.Count > 5 then
      sl.Delete(sl.Count-1);
   for i := 0 to sl.Count - 1 do
          ini.WriteString('HISTORY',IntToStr(i+1),sl.Strings[i]);
   ini.UpdateFile;
   ini.Free;
   end;
fs := TMemoryStream.Create;
WriteComponentResFile('zCubeExplr.zrc',GridSettings);
end;

procedure TzExplorerForm.Exit1Click(Sender: TObject);
begin
Close;
end;

procedure TzExplorerForm.New1Click(Sender: TObject);
begin
CubeDefForm := TCubedefForm.Create(Self);
CubeDefForm.ShowModal;
CubedefForm.Free;
//CubeDefForm := TCubeDefForm.Create(Application);
//CubeDefForm.ShowModal;
//CubeDefForm.Free;
end;

procedure TzExplorerForm.Loadstructure1Click(Sender: TObject);
var
   ini : TIniFile;
   i,k : integer;
   d : TDimDef;
   m : TMeasureDef;
begin

if ODialog.Execute then
   begin
   LoadStructure(ODialog.FileName);
   CubeDefForm := TCubeDefForm.Create(Application);
   CubeDefForm.CubeDef := CubeDef;
   CubeDefForm.ShowModal;
   CubeDefForm.Free;

   end;
end;

procedure TzExplorerForm.SaveClick(Sender: TObject);
var
   ini : TIniFile;
   i : integer;
   s : string;
   sl : TStringList;
begin
if SDialog.Execute then
   begin
   // check for map exists
   try
   ini := TIniFile.Create(Cubedef.Name + '.map');
   sl := TStringList.Create;
   ini.ReadSections(sl);
   if sl.Count > 0 then
      begin
      if MessageDlg('Cube <' + CubeDef.Name + '> already was builded. ' +
                    'Do you wish clear saved maps for this cube? ' +
                    'Note: if you change cube structure, '+
                    'these maps can produce errors on loading!',
                    mtConfirmation,mbOKCancel,0) = mrOk then
         begin
         for i := 0 to sl.Count - 1 do
             ini.EraseSection(sl.Strings[i]);
         ini.UpdateFile;
         end;
      end;
   sl.Free;
      finally
      if ini <> nil then
         ini.Free;
      end;
   // save data
   ini := TIniFile.Create(SDIalog.FileName);
   ini.EraseSection('Main');
   ini.WriteString('Main','Name',CubeDef.Name);
   ini.WriteString('Main','Alias',CubeDef.AliasName);
   ini.WriteString('Main','Fact Table',CubeDef.FactTable);
   if Cubedef.SQL <> '' then
      begin
      s := '';
      for i := 1 to Length(Cubedef.SQL) do
          begin
          if (Ord(Cubedef.SQL[i]) < 32) then
             s := s + ' '
          else
             s := s + Cubedef.SQL[i];
          end;
      end;
   ini.WriteString('Main','SQL',s);
   ini.WriteString('Main','FieldCount',IntToStr(CubeDef.Fields.Count));
   for i := 0 to CubeDef.Fields.Count - 1 do
       begin
       ini.EraseSection('F'+IntToStr(i));
       ini.WriteString('F' + IntToStr(i),'FieldName',CubeDef.Fields[i]);
       end;
   ini.WriteString('Main','DimCount',IntToStr(CubeDef.Dimensions.Count));
   for i := 0 to CubeDef.Dimensions.Count - 1 do
       begin
       ini.EraseSection('D'+IntToStr(i));
       ini.WriteString('D' + IntToStr(i),'AliasName',TDimDef(CubeDef.Dimensions.Objects[i]).AliasName);
       ini.WriteString('D' + IntToStr(i),'FieldName',TDimDef(CubeDef.Dimensions.Objects[i]).FieldName);
       ini.WriteInteger('D' + IntToStr(i),'DataType',Ord(TDimDef(CubeDef.Dimensions.Objects[i]).DataType));
       ini.WriteString('D' + IntToStr(i),'Table',TDimDef(CubeDef.Dimensions.Objects[i]).TableName);
       ini.WriteString('D' + IntToStr(i),'Key',TDimDef(CubeDef.Dimensions.Objects[i]).KeyField);
       ini.WriteString('D' + IntToStr(i),'Lookup',TDimDef(CubeDef.Dimensions.Objects[i]).LookupField);
       ini.WriteBool('D' + IntToStr(i),'Branch',TDimDef(CubeDef.Dimensions.Objects[i]).isBranch);
       if TDimDef(CubeDef.Dimensions.Objects[i]).isBranch then
          ini.WriteString('D' + IntToStr(i),'MasterTable',TDimDef(CubeDef.Dimensions.Objects[i]).MasterTable);
       end;
   ini.WriteString('Main','MeasureCount',IntToStr(CubeDef.Measures.Count));
   for i := 0 to CubeDef.Measures.Count - 1 do
       begin
       ini.EraseSection('M'+IntToStr(i));
       ini.WriteString('M' + IntToStr(i),'Alias',TMeasureDef(CubeDef.Measures.Objects[i]).AliasName);
       ini.WriteString('M' + IntToStr(i),'Name',TMeasureDef(CubeDef.Measures.Objects[i]).FieldName);
       ini.WriteInteger('M' + IntToStr(i),'Type',Ord(TMeasureDef(CubeDef.Measures.Objects[i]).MeasureType));
       ini.WriteInteger('M' + IntToStr(i),'DataType',Ord(TMeasureDef(CubeDef.Measures.Objects[i]).DataType));
       end;
   ini.UpdateFile;
   ini.Free;
   end;
end;

procedure TzExplorerForm.BuildCube;
var
   i,k : integer;
   t1,t2 : TDateTime;
   isdate : boolean;
begin
t1 := Time;
FCube := CoCube.Create;
FCube.Name := CubeDef.Name;
FCube.SetAlias(CubeDef.AliasName,'','');
if CubeDef.SQL <> '' then
   CubeDef.FactTable := ProcessSQL(CubeDef.AliasName,CubeDef.SQL);
FCube.SetTableName(CubeDef.FactTable,False);
for i := 0 to CubeDef.Dimensions.Count - 1 do
    begin
    if (TDimDef(CubeDef.Dimensions.Objects[i]).DataType = ftDate) or
       (TDimDef(CubeDef.Dimensions.Objects[i]).DataType = ftDateTime) then
       k := wtYears + wtDays
    else
       k := 0;
    FCube.AddDimension(TDimDef(CubeDef.Dimensions.Objects[i]).AliasName,
                       TDimDef(CubeDef.Dimensions.Objects[i]).FieldName,
                       TDimDef(CubeDef.Dimensions.Objects[i]).TableName,
                       TDimDef(CubeDef.Dimensions.Objects[i]).KeyField,
                       TDimDef(CubeDef.Dimensions.Objects[i]).LookupField,
                       TDimDef(CubeDef.Dimensions.Objects[i]).MasterTable,
                       k);
    end;
for i := 0 to CubeDef.Measures.Count - 1 do
    FCube.AddMeasure(TMeasureDef(CubeDef.Measures.Objects[i]).AliasName,
                     TMeasureDef(CubeDef.Measures.Objects[i]).FieldName,
                     TMeasureDef(CubeDef.Measures.Objects[i]).MeasureType);
try
   Monitor := CoLoadMonitor.Create;
   FCube.InitMonitor(Monitor);

   FCube.CreateCube(i);
   if Monitor <> nil then
      Monitor := nil;
   try
      MapForm := TMapForm.Create(Self);
      MapForm.GridSettings := GridSettings;
      MapForm.Cube := FCube;
      FCube := nil;
      except
            MapForm.Free;
            raise;
      end;
   except
      FCube := nil;
      if Monitor <> nil then
         Monitor := nil;
      Application.HandleException(Self);
      Exit;
   end;
t2 := Time;
Windows.MessageBox(Handle,
                   PChar('Cells = ' + IntToStr(i) +
                        #13#10 +' Load time = ' + IntToStr(MillisecondsBetween(t1,t2)))
                  ,PChar('Cude created')
                  ,MB_ICONINFORMATION+MB_OK);

PrintItem.Enabled := True;
end;

procedure TzExplorerForm.HistoryCLick(Sender: TObject);
var
   s : string;
begin
if Sender is TMenuItem then
   begin
   s := (Sender as TMenuItem).Caption;
   Delete(s,Pos('&',s),1);
   LoadStructure(s);
   BuildCube;
   end;
end;

procedure TzExplorerForm.LoadStructure(FileName: string);
var
   ini : TIniFile;
   i,j,k : integer;
   d : TDimDef;
   m : TMeasuredef;
begin
   ini := TIniFile.Create(FileName);
   if CubeDef = nil then
      CubeDef := TCubeDef.Create
   else
      CubeDef.Clear;
   CubeDef.Name := ini.ReadString('Main','Name','');
   CubeDef.AliasName := ini.ReadString('Main','Alias','');
   CubeDef.FactTable := ini.ReadString('Main','Fact Table','');
   CubeDef.SQL := ini.ReadString('Main','SQL','');
   k := ini.ReadInteger('Main','FieldCount',0);
   for i := 0 to k - 1 do
       begin
       CubeDef.Fields.Add(ini.ReadString('F' + IntToStr(i),'FieldName',''));
       end;
   k := ini.ReadInteger('Main','DimCount',0);
   for i := 0 to k - 1 do
       begin
       d := TDimDef.Create;
       d.AliasName := ini.ReadString('D' + IntToStr(i),'AliasName','');
       d.FieldName := ini.ReadString('D' + IntToStr(i),'FieldName','');
       d.DataType := TFieldType(ini.ReadInteger('D' + IntToStr(i),'DataType',0));
       d.TableName := ini.ReadString('D' + IntToStr(i),'Table','');
       d.KeyField := ini.ReadString('D' + IntToStr(i),'Key','');
       d.LookupField := ini.ReadString('D' + IntToStr(i),'Lookup','');
       d.isBranch := ini.ReadBool('D' + IntToStr(i),'Branch',False);
       if d.isBranch then
          d.MasterTable := ini.ReadString('D' + IntToStr(i),'MasterTable','');
       if d.FieldName <> '' then
          CubeDef.Dimensions.AddObject(d.FieldName,d);
       end;
   k := ini.ReadInteger('Main','MeasureCount',0);
   for i := 0 to k - 1 do
       begin
       m := TMeasureDef.Create;
       m.AliasName := ini.ReadString('M' + IntToStr(i),'Alias','');
       m.FieldName := ini.ReadString('M' + IntToStr(i),'Name','');
       m.MeasureType := TMeasureType(ini.ReadInteger('M' + IntToStr(i),'Type',0));
       m.DataType := TFieldType(ini.ReadInteger('M' + IntToStr(i),'DataType',0));
       if m.FieldName <> '' then
          CubeDef.Measures.AddObject(m.FieldName,m);
       end;
   ini.Free;
end;

procedure TzExplorerForm.Color1Click(Sender: TObject);
var
   i : integer;
begin
ColorsForm := TColorsForm.Create(Self);

ColorsForm.ColumnsCB.Selected := GridSettings.ColumnHeaderColor;
ColorsForm.RowsCB.Selected    := GridSettings.RowheaderColor;
ColorsForm.CellCB.Selected    := GridSettings.CellColor;
COlorsForm.SelCellCB.Selected := GridSettings.SelectedCellColor;
COlorsForm.FCellCB.Selected   := GridSettings.FocusedCellColor;


if ColorsForm.ShowModal = mrOk then
   begin
   GridSettings.ColumnHeaderColor := ColorsForm.ColumnsCB.Selected;
   GridSettings.RowheaderColor    := ColorsForm.RowsCB.Selected;
   GridSettings.CellColor         := ColorsForm.CellCB.Selected;
   GridSettings.SelectedCellColor := COlorsForm.SelCellCB.Selected;
   GridSettings.FocusedCellColor  := COlorsForm.FCellCB.Selected;
   end;
ColorsForm.Free;
for i := 0 to MDIChildCount - 1 do
    begin
    TMapForm(MDIChildren[i]).Grid.Repaint;
    end;
end;

procedure TzExplorerForm.Fonts1Click(Sender: TObject);
begin
FontsForm := TFontsForm.Create(Self);
FontsForm.ColHeaderEdit.Color := gridSettings.ColumnHeaderColor;
FontsForm.ColHeaderEdit.Font.Assign(GridSettings.ColumnHeaderFont);
FontsForm.RowHeaderEdit.Color := gridSettings.RowHeaderColor;
FontsForm.RowHeaderEdit.Font.Assign(GridSettings.RowHeaderFont);
FontsForm.PCellEdit.Color := gridSettings.CellColor;
FontsForm.PCellEdit.Font.Assign(GridSettings.PositiveCellFont);
FontsForm.NCellEdit.Color := gridSettings.CellColor;
FontsForm.NCellEdit.Font.Assign(GridSettings.NegativeCellFont);
FontsForm.ZCellEdit.Color := gridSettings.CellColor;
FontsForm.ZCellEdit.Font.Assign(GridSettings.ZeroCellFont);
if FontsForm.ShowModal = mrOk then
   begin
   GridSettings.ColumnHeaderFont.Assign(FontsForm.ColHeaderEdit.Font);
   GridSettings.RowHeaderFont.Assign(FontsForm.RowHeaderEdit.Font);
   GridSettings.PositiveCellFont.Assign(FontsForm.PCellEdit.Font);
   GridSettings.NegativeCellFont.Assign(FontsForm.NCellEdit.Font);
   GridSettings.ZeroCellFont.Assign(FontsForm.ZCellEdit.Font);
   end;
FontsForm.Free;
end;

procedure TzExplorerForm.PrintItemClick(Sender: TObject);
begin
if MDIChildCount = 0 then
   begin
   PrintItem.Enabled := False;
   Exit;
   end;
TMapForm(ActiveMDIChild).PrintMap;
end;

procedure TzExplorerForm.Exit2Click(Sender: TObject);
begin
Close;
end;

procedure TzExplorerForm.FormPaint(Sender: TObject);
begin
if MDIChildCount = 0 then
   PrintItem.Enabled := False;
end;

procedure TzExplorerForm.Cascade1Click(Sender: TObject);
begin
Cascade;
end;

procedure TzExplorerForm.ile1Click(Sender: TObject);
begin
Tile;
end;

procedure TzExplorerForm.ArrangeIcons1Click(Sender: TObject);
begin
ArrangeIcons;
end;

procedure TzExplorerForm.Load1Click(Sender: TObject);
var
   LoadCubeForm : TLoadCubeForm;
   ISL : IStrings;
   t1,t2 : TDateTime;
begin
LoadCubeForm := TLoadCubeForm.Create(Self);
try
   if FCube = nil then
      FCube := CoCube.Create;
   FCube.GetSavedCubesList(ISL);
   if ISL <> nil then
      begin
      SetOLEStrings(LoadCubeForm.ListLB.Items,ISL);
      if LoadCubeForm.ShowModal = mrOK then
         begin
         try
            t1 := Time;
            Monitor := CoLoadMonitor.Create;
            FCube.InitMonitor(Monitor);
            FCube.Load(LoadCubeForm.ListLB.Items[LoadCubeForm.ListLB.ItemIndex]);
            Monitor := nil;
            try
               MapForm := TMapForm.Create(Self);
               MapForm.GridSettings := GridSettings;
               MapForm.Cube := FCube;
               FCube := nil;
               t2 := Time;
               Windows.MessageBox(Handle,
                   PChar('Cells = ' + IntToStr(MapForm.Cube.CubeLength) +
                        #13#10 +' Load time = ' + IntToStr(MillisecondsBetween(t1,t2)))
                  ,PChar('Cude created')
                  ,MB_ICONINFORMATION+MB_OK);
               except
                     MapForm.Free;
                     raise;
               end;
            except
            if Monitor <> nil then
               Monitor := nil;
            FCube := nil;
            raise;
            end;
         end
      else
         FCube := nil;
      end
   else
      FCube := nil;
   finally
          LoadCubeForm.Free;
   end;
PrintItem.Enabled := True;
end;

procedure TzExplorerForm.Save1Click(Sender: TObject);
var
   s : string;
begin
if ActiveMDIChild <> nil then
   begin
   s := InputBox('Saving cube','Enter name',TMapForm(ActiveMDIChild).Cube.Name);
   Application.ProcessMessages;
   if s <> '' then
      TMapForm(ActiveMDIChild).Cube.Save(s);
   end
else
   ShowMessage('No cube loaded'); 
end;


function TzExplorerForm.ProcessSQL(Alias, SQL: string): string;
var
   i : integer;
   tbl : TTable;
   qry : TQuery;
begin
try
   tbl := TTable.Create(nil);
   tbl.TableType := ttDBase;
   tbl.DatabaseName := Alias;
   tbl.TableName := 'zExplorerTempBase.dbf';
   qry := TQuery.Create(nil);
   qry.DatabaseName := Alias;
   qry.SQL.Clear;
   qry.SQL.Add(SQL);
   qry.Open;
   try
      tbl.FieldDefs.Clear;
      for i := 0 to qry.FieldCount - 1 do
          begin
          with tbl.FieldDefs.AddFieldDef do
               begin
               Name := qry.Fields[i].FieldName;
               DataType := qry.Fields[i].DataType;
               end;
          end;
      tbl.CreateTable;
      tbl.Open;
      qry.First;
      while not qry.Eof do
            begin
            tbl.Insert;
            for i := 0 to qry.FieldCount - 1 do
                tbl.Fields[i].AsString := qry.Fields[i].AsString;
            tbl.Post;
            qry.Next;
            end;
      except
      Application.HandleException(Self);
      end;
   Result := tbl.TableName;
   finally
          qry.Close;
          qry.Free;
          tbl.Close;
          tbl.Free;
   end;
end;

end.
