
{*******************************************************}
{                                                       }
{       Borland Delphi Visual Component Library         }
{                                                       }
{       Copyright (c) 1997,98 Inprise Corporation       }
{                                                       }
{*******************************************************}

unit mxDB;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Bde, DB, DBTables, Menus, mxArrays, mxStore, mxConsts, mxcommon, mxtables, mxqparse, mxqedcom;

type
  EArrayError = class(Exception);
	EDimIndexError = class(Exception);
  TDimGroup = (dgRow, dgCol, dgSum, dgPage, dgNone);
  TRowStates = (rcNextOpen, rcPrevOpen,
                rcNextClosed, rcPrevClosed);
	TRowState = set of TRowStates;
	TDimState = (dmClosed, dmOpen, dmDrilled, dmPaged, dmNone);
	TDecisionControlType = (xtCheck, xtRadio, xtRadioEx);
	TIArray = class
  protected
    function  GetItem(Index: Integer): Integer;       //Fetch array element
    procedure SetItem(Index: Integer; Value: Integer);//Put array element
  public
    constructor Create(ALimit: Integer; ABlockSize: Integer);                          //create to a specified size
    destructor Destroy; override;
    procedure Assign(Value: TIArray);                           //copy from another TIArray
    procedure InsertAt(Index: Integer; Value: Integer);           //insert a new item at Index
    function  RemoveItem(Index: Integer): Integer;                //remove the item at Index
    property AutoSize: Boolean;
    property Limit: Integer;
    property Items[Index: Integer]: Integer; default;  //pseudo array access

  end;
    PArrayInt = ^TArrayInt;
  TArrayInt = array[0..MaxInt div 8] of Integer;


	TDimInfo = Record
  	iState: TDimState;
		iValue: Integer;      	// value index if drilled
		iIndex: Integer;				// position in row or column array
    iActiveIndex: Integer;  // Active position
		iRowState: TRowState;
    iGroup: TDimGroup;
  end;


  TDimRange = Record
    First: Integer;
    Last: Integer;
  end;

	TBigStr = array[0..100000] of  Char;
  PDimInfo = ^TDimInfo;
  TArrayDimInfo = array[0..999] of TDimInfo;
  PArrayDimInfo = ^TArrayDimInfo;

  TDimInfoArray = class
  protected
    function  GetItem(Index: Integer): PDimInfo;       //Fetch array element
    function Find(Name: string; var pos: integer): boolean;
    //    procedure SetItem(Index: Integer; Value: TDimInfo);//Put array element
  public
    constructor Create(ALimit: Integer);                          //create to a specified size
    destructor Destroy; override;
    procedure Assign( Value: TDimInfoArray);
    function GetGroupItem(Group: TDimGroup; Index: integer; bOpen: boolean): PDimInfo;
    function GetGroupIndex(Group: TDimGroup; Index: integer; bOpen: boolean): integer;
		function GetGroupSize(Group: TDimGroup; bOpen: boolean): integer;
		function GetGroupArray(Group: TDimGroup; bOpen: boolean): TIArray;
		function IsEqual( Value: TDimInfoArray): boolean;
    property Limit: Integer;
    property Items[Index: Integer]: PDimInfo; default;  //pseudo array access
  end;

  TPivotState = class
    protected
      procedure Assign(Value: TPivotState);
			function IsEqual(Value: TPivotState): boolean;
    public
  		FDims:	Integer;								//Total Dimension count
			FSums:	Integer;
			FCurrentSum: Integer;
			FRowSubs: Boolean;           //Row Subtotals on/off
  	  FColSubs: Boolean;						//Column Subtotals on/off
			FRowSparse: Boolean;					//Display Sparse Rows on/off
      FColSparse: Boolean;
			DimInfo: TDimInfoArray;
      Constructor Create;
      Destructor Destroy; override;
  end;


	TDecisionCube = class;
  TDecisionSource = class;
  TDecisionDataEvent = (xeStateChanged, xeSummaryChanged, xePivot, xeNewMetaData, xeSourceChange);


  TDecisionDataLink = class(TPersistent)
  public
		constructor Create;
		destructor Destroy; override;
		property DecisionSource: TDecisionSource read FDecisionSource write SetDecisionSource;
  end;

  TDecisionSource = class(TComponent)
	 private
		FChangeCount: integer;
		FState: TCubeState;
		bActivated: boolean;
		FBlocked: Boolean;
		FDecisionCube:	TDecisionCube;
		FControlType: TDecisionControlType;

    FDecisionDataLinks: TList;
    FSavePivotState: TPivotState;
    FData: TPivotState;     // will become protected
    RowLookup: TTwoDimArray;    //address vectors for all visible rows
    ColLookup: TTwoDimArray;    //address vectores for all visibile columns


			FRowMax: Integer;             //number of rows in the row lookup
  	  FColMax: Integer;							//number of columns in the col lookup
			FActiveRows: Integer;
			FActiveCols: Integer;
			FAllRows: Integer;
			FAllPages: Integer;
      FAllCols: Integer;

//	  procedure SetActive(Value: Boolean);
		procedure SetUpData;
	  procedure RebuildPivotState;
	  procedure BuildLookups;
//		function GetActive: Boolean;
		function GetReady: Boolean;
		procedure AddDatalink (link: TDecisionDatalink);
		procedure RemoveDatalink (link: TDecisionDatalink);
		procedure NotifyDataLinks(Event: TDecisionDataEvent);
//		function GetDimensions: Integer;
    procedure DefineProperties(Filer: TFiler); override;
		procedure ReadDimCount(Reader: TReader);
		procedure WriteDimCount(Writer: TWriter);
		procedure ReadSumCount(Reader: TReader);
		procedure WriteSumCount(Writer: TWriter);
		procedure ReadCurrentSum(Reader: TReader);
		procedure WriteCurrentSum(Writer: TWriter);
		procedure ReadRowSparse(Reader: TReader);
		procedure WriteRowSparse(Writer: TWriter);
		procedure ReadColSparse(Reader: TReader);
		procedure WriteColSparse(Writer: TWriter);
		procedure ReadDimInfo(Reader: TReader);
		procedure WriteDimInfo(Writer: TWriter);

		function GetExampleRepCount(dimGroup: TDimGroup; level: Integer): Integer;
		procedure DrillValue(iDim: Integer; ValueIndex: Integer);
		procedure	DecisionDataEvent(Event: TDecisionDataEvent);
    procedure EnforceConstraints(dimGroup: TDimGroup; PreserveIndex: Integer);
    function GetRowSparsing: boolean;
    function GetColSparsing: boolean;
    procedure SetRowSparsing(Value: boolean);
    procedure SetColSparsing(Value: boolean);
//    property 	Active: boolean read GetActive write SetActive;
//		function 	Lookup(dimGroup: TDimGroup; Index: Integer; Cell: Integer): Integer;
//		procedure SetFormat(isDim: boolean; iDim: Integer; aFormat: String);
		function	GetDecisionCube: TDecisionCube;
    procedure SetDecisionCube(Value: TDecisionCube);
	  function GetDims: integer;
    function GetSums: integer;
    function GetCurrentSum: integer;
//      procedure SCurrentSum(value: integer);
//		procedure SetDimInfo(iDim: integer; aDiminfo: pDimInfo); virtual;

//  QA interfaces
 		procedure ProcessPivotState(FState: TPivotState);
    procedure FetchPivotState (var FState: TPivotState); virtual;
    procedure StorePivotState(FState: TPivotState); virtual;
		procedure BeginChange; virtual;
		procedure EndChange(event: TDecisionDataEvent); virtual;

	protected

		procedure SetDimGroup(iDim: integer; Group: TDimGroup; Index: integer; bOpen: boolean);
		procedure SetDimState(iDim: integer; State: TDimState; ValueIndex: integer);

  public
//
//
//	Pivot State Access
//
//	Hooks
		FOnBeforePivot:	TNotifyEvent;
		FOnAfterPivot:	TNotifyEvent;
		FOnStateChange: TNotifyEvent;
		FOnNewDimensions: TNotifyEvent;
		FOnLayoutChange: TNotifyEvent;
    FonSummaryChange: TNotifyEvent;
//
    constructor Create( AOwner: TComponent ); override;
		destructor Destroy; override;
//
//	Meta data and data fetching
    function  GetMemberAsString(iDim: Integer; ValueIndex: Integer): String;
    function  GetMemberAsVariant(iDim: Integer; ValueIndex: Integer): Variant;
    function  GetDimensionName(iDim: Integer): String;
    function  GetDimensionMemberCount(iDim: Integer): Integer;
    function  GetSummaryName(iSum: Integer): String;
    procedure SetCurrentSummary(Value: Integer);

//	Graph specific data fetching
    function  Get2DDataAsVariant(iDimA, iDimB: Integer; aValueIndex, bValueIndex:Integer): Variant;

//	Grid specific data fetching
    function  GetDataAsString(ARow, ACol:Integer; var SubLevel: Integer): String;
		function  GetDataAsVariant(Arow, ACol: Integer; var SubLevel: Integer): Variant;
    function 	GetValueIndex(dimGroup: TDimGroup; Index: Integer; Cell: Integer; var isBreak: boolean; var isSum: boolean) : Integer;
		function 	GetValueArray(ACol, ARow: Integer; var ValueArray: TSmallIntArray): boolean;
    function 	GetGroupExtent(dimGroup: TDimGroup; Index: Integer; Cell: Integer): TDimRange;
//
//  Active or Inactive Row/Col relative pivoting functions
		function 	GetActiveDim(dimGroup: TDimGroup; index: Integer; bOpen: boolean): Integer;
		procedure OpenDimIndexRight(dimGroup: TDimGroup; Index: Integer; bOpen: boolean);
		procedure CloseDimIndexRight(dimGroup: TDimGroup; Index: Integer; bOpen: boolean);
		procedure OpenDimIndexLeft(dimGroup: TDimGroup; Index: Integer; bOpen: boolean);
		procedure ToggleDimIndex(dimGroup: TDimGroup; Index: Integer; bOpen: boolean);
		procedure DrillDimIndex(dimGroup: TDimGroup; Index: Integer; ValueIndex: Integer; bOpen:boolean);
		procedure MoveDimIndexes(SdimGroup, DdimGroup: TDimGroup; SIndex, DIndex: Integer; bOpen:boolean);
		procedure SwapDimIndexes(SdimGroup, DdimGroup: TDimGroup; SIndex, DIndex: Integer; bOpen:boolean);

    function GetGroupCount(dimGroup: TDimGroup; bOpen: boolean):integer;

		function GetGroup(iDim: integer):TDimGroup;
		function GetIndex(iDim: integer; bOpen: boolean): integer;
		function GetState(iDim: integer): TDimState;
		function GetValue(iDim: integer): integer;
		function GetRowState(iDim: integer): TRowState;

		property 	Ready: Boolean read GetReady;
//
//  pivot State Information
    property nDims: integer;
    property nSums: integer;
    property nRowDims: integer;
    property nColDims: integer;
    property nOpenRowDims: integer;
    property nOpenColDims: integer;
    property nDataRows: integer;
    property nDataCols: integer;
    property CurrentSum: integer;

 published
  	property DecisionCube: TDecisionCube read GetDecisionCube write SetDecisionCube;
		property ControlType: TDecisionControlType read FControlType write FControlType;
  	property Name;
    property SparseRows: boolean;
    property SparseCols: boolean;
    property OnStateChange: TNotifyEvent;
    property OnNewDimensions: TNotifyEvent;
    property OnLayoutChange: TNotifyEvent;
    property OnSummaryChange: TNotifyEvent;
    property OnBeforePivot: TNotifyEvent;
    property OnAfterPivot: TNotifyEvent;
  end;

  TQADecisionSource = class(TDecisionSource)
  public
		procedure BeginChange; override;
		procedure EndChange(event: TDecisionDataEvent); override;
    procedure FetchPivotState(var FState: TPivotState); override;
    procedure StorePivotState(FState: TPivotState); override;
  published
  end;

  TDecisionCube = class(TCustomDataStore)
  public
    constructor Create( AOwner: TComponent ); override;
    destructor Destroy; override;
    property  DesignState;
//    function  GetDimensionName( Dimension: Integer ): String; override;
//    function  GetDimensionMemberCount( Dimension: Integer ): Integer; override;
//    function  GetMember( Dimension, Index: Integer ): String;
//    function  GetSummaryName( ISum: Integer ): String; override;
		 function	GetSQL( ValueArray: TSmallIntArray; bActive: boolean ): string;
		 function	GetDetailSQL( ValueArray: TSmallIntArray; SelectList: string; bActive: boolean): string;
    procedure ShowCubeDialog;
{$IFDEF PDEBUGS}
    procedure ShowSQLDialog(SQL: string);
    procedure ShowQueryDialog;
{$ENDIF}
{$IFDEF PROFILE}
    procedure CreateIndexTable( Const Filename: String );
    function  GetLogFile: string;
    procedure SetLogFile( fName: string );
{$ENDIF}
    property  Active: Boolean;
  published
    property  DataSet;
    property  DimensionMap;
    property  ShowProgressDialog;
		 property  MaxDimensions;
		 property  MaxSummaries;
     property  MaxCells;
    property  OnLowCapacity;
    property  BeforeOpen;
    property  AfterOpen;
    property  BeforeClose;
    property  AfterClose;
    property  OnRefresh;
{$IFDEF PROFILE}
    property ProfileLogFile: string;
{$ENDIF}
  end;

implementation
