unit uOSMark;
{
  COSBI: Comprehensive Open Source Benchmarking Initiative
  Copyright (c) 2004 Van Smith

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

  The current web address of the GNU General Public License is:
  http://www.gnu.org/licenses/gpl.html

  You can contact the authors of this software at:
  cosbi@vanshardware.com
  See www.vanshardware.com or www.cosbi.org for more contact details.
}
//==============================================================================
// Unit name: uOSMark
// Unit description: This unit is the form unit for OSMark.
// Author: Van Smith
// Date: March 24, 2003
// OS dependent: Yes: Windows
// Resolution dependent: No, but resolution and color depth will impact scores.
// External unit dependencies: COSBI_Common, uCOSBI_TestBaseClass, GR32_Blend,
//   GR32_Image, GR32, Maze
//==============================================================================
// Modification History
// ------------ -------
// Ver  Date   Who    Description
// ==== ====== ====== ==========================================================
// 1.0 020503 Van     Created.
//==============================================================================

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, COSBI_Common, StdCtrls, uCOSBI_SystemInfo, uTests, uOutput,
  Gauges, GR32, Dhrystone, Whetstone, uOSMarkSuite, uCOSBI_TTest,
  ZipForge, uOSMarkResults, ufrmCPUInfo, Buttons, jpeg, ExtCtrls, FileCtrl,
  ComCtrls, IniFiles, frmBandwidthBurn, frmMemLatencyPlus, uFileCopy,
  ufrmWhetBurn, MPlayer;

type

  TfrmOSMark = class(TForm)
    btnRun: TButton;
    memoResults: TMemo;
    gbSelectTests: TGroupBox;
    cboxGridBlast: TCheckBox;
    cboxRandomCircle: TCheckBox;
    cboxPlotTrig: TCheckBox;
    cboxPlotLines: TCheckBox;
    cboxRandDots: TCheckBox;
    cboxFib: TCheckBox;
    cboxNBody: TCheckBox;
    Timer: TGroupBox;
    radioLow: TRadioButton;
    radioHigh: TRadioButton;
    radioCPU: TRadioButton;
    cboIterations: TComboBox;
    lblIterations: TLabel;
    cboxMaze: TCheckBox;
    pBar: TGauge;
    cboxTrig2: TCheckBox;
    cboxFern: TCheckBox;
    btnSave: TButton;
    cboxRichEd: TCheckBox;
    cboxCalculatePi: TCheckBox;
    cboxDhry: TCheckBox;
    cboxWhet: TCheckBox;
    SaveDialog1: TSaveDialog;
    GroupBox_Priority: TGroupBox;
    radioNormalP: TRadioButton;
    radioHighP: TRadioButton;
    radioRealtimeP: TRadioButton;
    cboxBandwidthBP64: TCheckBox;
    cboxLatency: TCheckBox;
    cboxMazeThreads: TCheckBox;
    cboxGridBlastFP: TCheckBox;
    cboxOThreads: TCheckBox;
    cboxIThreads: TCheckBox;
    cboxImageRotate: TCheckBox;
    cboxJpgDecode: TCheckBox;
    cboxImageResize: TCheckBox;
    cboxMP3Encode: TCheckBox;
    cboxWebPageLoad: TCheckBox;
    cboxEncryptDecrypt: TCheckBox;
    cboxZipCompress: TCheckBox;
    cboxFileCopy: TCheckBox;
    btnResults: TButton;
    btnAbout: TButton;
    btnCPUInfo: TButton;
    Image1: TImage;
    BitBtnOfficialRun: TBitBtn;
    cboxLorenz: TCheckBox;
    DriveComboBoxTarget: TDriveComboBox;
    Label1: TLabel;
    StatusBar1: TStatusBar;
    cboxNBodyOpenGL: TCheckBox;
    Timer1: TTimer;
    btnBandwidthBurn: TButton;
    btnMemLatencyPlus: TButton;
    btnWhetBurn: TButton;
    btnCpuSpeed: TButton;
    btnCpuUtilization: TButton;
    btnFileCopy: TButton;
    BitBtnMobile: TBitBtn;
    BitBtnThinClient: TBitBtn;
    GroupBox1: TGroupBox;
    cboxSpinUp: TCheckBox;
    cboxStatus: TCheckBox;
    cboxProcessIdleTasks: TCheckBox;
    cboxDefragDrive: TCheckBox;
    btnThreadWrecker: TButton;
    cboxDhrystoneThreads: TCheckBox;
    cboxWhetstoneThreads: TCheckBox;
    cboxPiThreads: TCheckBox;
    btnSelectNone: TButton;
    btnSelectAll: TButton;
    cboxMandelbrot: TCheckBox;
    cboxEllipses: TCheckBox;
    cboxRectangles: TCheckBox;
    cboxLines: TCheckBox;
    cboxFibThreads: TCheckBox;
    MediaPlayer1: TMediaPlayer;
    MediaPlayerAbout: TMediaPlayer;
    BitBtnQuit: TBitBtn;
    cboxMaxPowerDraw: TCheckBox;
    cboxPngOut: TCheckBox;
    cbox7zip: TCheckBox;
    cboxUpx: TCheckBox;
    procedure BitBtnQuitClick(Sender: TObject);
    procedure BitBtnOfficialRunKeyPress(Sender: TObject; var Key: Char);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure cboxDefragDriveClick(Sender: TObject);
    procedure cboxProcessIdleTasksClick(Sender: TObject);
    procedure cboxStatusClick(Sender: TObject);
    procedure cboxSpinUpClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnRunClick(Sender: TObject);
    procedure btnSelectAllClick(Sender: TObject);
    procedure btnSelectNoneClick(Sender: TObject);
    procedure ClearOutput;
    procedure radioLowClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure radioRealtimePClick(Sender: TObject);
    procedure btnResultsClick(Sender: TObject);
    procedure btnAboutClick(Sender: TObject);
    procedure btnCPUInfoClick(Sender: TObject);
    procedure BitBtnOfficialRunClick(Sender: TObject);
    procedure InitializeOSMarkTestSuite;
    procedure UpdateStatusMemo( Sender: TObject );
    procedure OnTestSuiteRunStart( Sender: TObject );
    procedure OnIterationStart( Sender: TObject );
    procedure OnTestBegins( Sender: TObject );
    procedure OnTestEnds( Sender: TObject );
    procedure OnTestSuiteRunEnd( Sender: TObject );
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
    procedure btnBandwidthBurnClick(Sender: TObject);
    procedure btnMemLatencyPlusClick(Sender: TObject);
    procedure btnFileCopyClick(Sender: TObject);
    procedure btnWhetBurnClick(Sender: TObject);
    procedure btnCpuSpeedClick(Sender: TObject);
    procedure btnCpuUtilizationClick(Sender: TObject);
    procedure btnThreadWreckerClick(Sender: TObject);
    procedure BitBtnMobileClick(Sender: TObject);
    procedure BitBtnThinClientClick(Sender: TObject);
  private
    { Private declarations }
    fStopWatch: TStopWatch;
    fSystemInfo: TSystemInfo;
    frmOutput: TfrmOutput;
    fbOfficialRun : Boolean;
    fbCommandLineRun : Boolean;
    fOSMarkTestSuite : TOSMarkTestSuite;
    fTestStart : TDateTime;
    frmBandwidthBurn : TfrmCOSBIBandwidthBurn;
    frmMemLatencyPlus : TfrmMemLate;
    frmCopyFile : TfrmCopyFile;
    frmWhetBurn :  TfrmWhetBurn;
    fbSpinUp : Boolean;
    fbShowStatus : Boolean;
    fbProcessIdleTasks : Boolean;
    fbDefragDrive : Boolean;
    //frmCPUSpeed : TfrmCPUSpeed;
    procedure SetPriority;
    procedure OfficialRun;
    procedure RunTests;
    procedure RunSelectedTests( aiInterate : integer; aSelectedTests: TQTestSet );
    procedure ClearStatusBar;
    procedure ParseCommandLine;
    procedure ReadIniFile;
    procedure WriteIniFile;
    procedure ProcessIdleTasks;
    procedure Defrag;
    procedure LinkEventHandlers;
    function GetSelectedTests: TQTestSet;
    function GetIterations: integer;
    procedure CheckOfficialRunTests;
  public
    { Public declarations }
    function  CountTests: integer;
    procedure CheckUncheckBoxes(ab_Checked : Boolean);
  end;

const
  VERSION = '1.0beta7a';
  DEFAULT_FILENAME = 'OSMarkResults.txt';
  DEFAULT_MOBILE_FILENAME = 'OSMarkMobileResults.txt';
  PANEL_MAIN = 0;
  PANEL_LAST_RESULT = 1;
  PANEL_ITERATION = 2;
  PANEL_TIME = 3;
  PANEL_LOOP = 4;
  REFERENCE_NB_PERFORMANCE_SCORE = 748.4; // Score for 1.5GHz Banias in Dell Inspiron 600m w/ 52.2WHr
  REFERENCE_NB_RUNDOWN_TIME = 8518.3; // in seconds for 1.5GHz Banias in Dell Inspiron 600m w/ 52.2WHr battery
  REFERENCE_NB_RUNDOWN_MAX_POWER_TIME = 5557.5; // in seconds for 1.5GHz Banias in Dell Inspiron 600m w/ 52.2WHr battery

var
  frmOSMark: TfrmOSMark;

implementation

{$R *.DFM}

procedure TfrmOSMark.LinkEventHandlers;
begin
    fOSMarkTestSuite.OnOutputString := UpdateStatusMemo;
    fOSMarkTestSuite.OnTestSuiteRunStart := OnTestSuiteRunStart;
    fOSMarkTestSuite.OnIterationStart := OnIterationStart;
    fOSMarkTestSuite.OnTestBegins := OnTestBegins;
    fOSMarkTestSuite.OnTestEnds := OnTestEnds;
    fOSMarkTestSuite.OnTestSuiteRunEnd := OnTestSuiteRunEnd;
end; // procedure TfrmOSMark.LinkEventHandlers;

procedure TfrmOSMark.ProcessIdleTasks;
begin
  StatusBar1.Panels[ PANEL_MAIN ].Text := 'Processing idle tasks...';
  memoResults.Lines.Add( 'Processing idle tasks...' );
  application.ProcessMessages;
  RunProcessIdleTasks;
  StatusBar1.Panels[ PANEL_MAIN ].Text := 'Finished processing idle tasks.';
  memoResults.Lines.Add( 'Finished processing idle tasks.' );
end; // procedure TfrmOSMark.ProcessIdleTasks;

procedure TfrmOSMark.Defrag;
var
  i : integer;
begin
  StatusBar1.Panels[ PANEL_MAIN ].Text := 'Defragging drive:' + DriveComboBoxTarget.Drive;
  memoResults.Lines.Add( 'Defragging drive: ' + DriveComboBoxTarget.Drive );
  for i := 1 to 5 do begin
    StatusBar1.Panels[ PANEL_MAIN ].Text := 'Defrag ' + intToStr( i ) + ' of 5';
    application.ProcessMessages;
    RunDiskDefrag( DriveComboBoxTarget.Drive, 1 );
  end; // for
  StatusBar1.Panels[ PANEL_MAIN ].Text := 'Finished disk defrag.';
  StatusBar1.Panels[ PANEL_MAIN ].Text := '';
  memoResults.Lines.Add( 'Defrag complete.' );
  application.ProcessMessages;
end; // procedure TfrmOSMark.Defrag;

procedure TfrmOSMark.SetPriority;
var
  H : THandle;
begin
  H := GetCurrentProcess();
  if radioNormalP.Checked then begin
    SetPriorityClass( H, NORMAL_PRIORITY_CLASS );
  end else if radioHighP.Checked then begin
    SetPriorityClass( H, HIGH_PRIORITY_CLASS );
  end else if radioRealtimeP.Checked then begin
    SetPriorityClass( H, REALTIME_PRIORITY_CLASS );
  end else raise exception.Create('Unknown program priority.');
end;

procedure TfrmOSMark.ReadIniFile;
var
  Ini: TIniFile;
begin
  Ini := TIniFile.Create( ChangeFileExt( Application.ExeName, '.INI' ) );
  try
    // read settings
    cboIterations.ItemIndex := Ini.ReadInteger('Settings', 'Iterations', 0 );
    cboxSpinUp.Checked      := Ini.ReadBool( 'Settings', 'SpinUp', TRUE );
    fbSpinUp                := cboxSpinUp.Checked;
    cboxStatus.Checked      := Ini.ReadBool( 'Settings', 'Status', TRUE );
    fbShowStatus                := cboxStatus.Checked;
    cboxDefragDrive.Checked := Ini.ReadBool( 'Settings', 'Defrag', TRUE );
    fbDefragDrive           := cboxDefragDrive.Checked;
    DriveComboBoxTarget.Drive := Ini.ReadString( 'Settings', 'TargetDrive', 'c' )[1];
    cboxProcessIdleTasks.Checked := Ini.ReadBool( 'Settings', 'ProcessIdleTasks', TRUE );
    fbProcessIdleTasks      := cboxProcessIdleTasks.Checked;
    // read tests
    cboxGridBlast.Checked   := Ini.ReadBool( 'Tests', 'GridBlast', TRUE );
    cboxGridBlastFP.Checked := Ini.ReadBool( 'Tests', 'GridBlastFP', TRUE );
    cboxFib.Checked         := Ini.ReadBool( 'Tests', 'Fib', TRUE );
    cboxNBody.Checked       := Ini.ReadBool( 'Tests', 'NBody', TRUE );
    cboxPlotTrig.Checked    := Ini.ReadBool( 'Tests', 'PlotTrig', TRUE );
    cboxTrig2.Checked       := Ini.ReadBool( 'Tests', 'PlotTrig2', TRUE );
    cboxPlotLines.Checked   := Ini.ReadBool( 'Tests', 'PlotLines', TRUE );
    cboxRandDots.Checked    := Ini.ReadBool( 'Tests', 'RandomDots', TRUE );
    cboxRandomCircle.Checked:= Ini.ReadBool( 'Tests', 'RandomCircles', TRUE );
    cboxMaze.Checked        := Ini.ReadBool( 'Tests', 'Mazes', TRUE );
    cboxFern.Checked        := Ini.ReadBool( 'Tests', 'Fern', TRUE );
    cboxRichEd.Checked      := Ini.ReadBool( 'Tests', 'RichEd', TRUE );
    cboxCalculatePi.Checked := Ini.ReadBool( 'Tests', 'CalculatePi', TRUE );
    cboxDhry.Checked        := Ini.ReadBool( 'Tests', 'Dhrystone', TRUE );
    cboxWhet.Checked        := Ini.ReadBool( 'Tests', 'Whetstone', TRUE );
    cboxMazeThreads.Checked := Ini.ReadBool( 'Tests', 'MazeThreads', TRUE );
    cboxBandwidthBP64.Checked:= Ini.ReadBool( 'Tests', 'BandwidthBP64', TRUE );
    cboxLatency.Checked     := Ini.ReadBool( 'Tests', 'MemLatency', TRUE );
    cboxOThreads.Checked    := Ini.ReadBool( 'Tests', 'OThreads', TRUE );
    cboxIThreads.Checked    := Ini.ReadBool( 'Tests', 'IThreads', TRUE );
    cboxJpgDecode.Checked   := Ini.ReadBool( 'Tests', 'JpgDecode', TRUE );
    cboxImageResize.Checked := Ini.ReadBool( 'Tests', 'ImageResize', TRUE );
    cboxImageRotate.Checked := Ini.ReadBool( 'Tests', 'ImageRotate', TRUE );
    cboxMp3Encode.Checked   := Ini.ReadBool( 'Tests', 'Mp3Encode', TRUE );
    cboxWebPageLoad.Checked := Ini.ReadBool( 'Tests', 'WebPageLoad', TRUE );
    cboxZipCompress.Checked := Ini.ReadBool( 'Tests', 'ZipCompress', TRUE );
    cboxEncryptDecrypt.Checked := Ini.ReadBool( 'Tests', 'EncryptDecrypt', TRUE );
    cboxFileCopy.Checked := Ini.ReadBool( 'Tests', 'FileCopy', TRUE );
    cboxLorenz.Checked := Ini.ReadBool( 'Tests', 'Lorenz', TRUE );
    cboxNBodyOpenGL.Checked := Ini.ReadBool( 'Tests', 'NBodyOpenGL', TRUE );
    cboxDhrystoneThreads.Checked := Ini.ReadBool( 'Tests', 'DhrystoneThreadTest', TRUE );
    cboxWhetstoneThreads.Checked := Ini.ReadBool( 'Tests', 'WhetstoneThreadTest', TRUE );
    cboxPiThreads.Checked := Ini.ReadBool( 'Tests', 'PiThreadTest', TRUE );
    cboxMandelbrot.Checked := Ini.ReadBool( 'Tests', 'MandelbrotTest', TRUE );
    cboxEllipses.Checked := Ini.ReadBool( 'Tests', 'EllipsesTest', TRUE );
    cboxRectangles.Checked := Ini.ReadBool( 'Tests', 'RectanglesTest', TRUE );
    cboxLines.Checked := Ini.ReadBool( 'Tests', 'LinesTest', TRUE );
    cboxFibThreads.Checked := Ini.ReadBool( 'Tests', 'FibThreadsTest', TRUE );
    cboxPngOut.Checked := Ini.ReadBool( 'Tests', 'PngOutThreadsTest', TRUE );
    cbox7zip.Checked := Ini.ReadBool( 'Tests', '7zipThreadsTest', TRUE );
    cboxUpx.Checked := Ini.ReadBool( 'Tests', 'UpxThreadsTest', TRUE );
  finally
    FreeAndNil( Ini );
  end; // try..finally
end; // procedure TfrmOSMark.ReadIniFile;

procedure TfrmOSMark.WriteIniFile;
var
  Ini: TIniFile;
begin
  Ini := TIniFile.Create( ChangeFileExt( Application.ExeName, '.INI' ) );
  try
    try
      // write settings
      Ini.WriteInteger( 'Settings', 'Iterations', cboIterations.ItemIndex );
      Ini.WriteBool( 'Settings', 'SpinUp', cboxSpinUp.Checked );
      Ini.WriteBool( 'Settings', 'Status', cboxStatus.Checked );
      Ini.WriteBool( 'Settings', 'Defrag', cboxDefragDrive.Checked );
      Ini.WriteString( 'Settings', 'TargetDrive', DriveComboBoxTarget.Drive );
      Ini.WriteBool( 'Settings', 'ProcessIdleTasks', cboxProcessIdleTasks.Checked );
      // write tests
      Ini.WriteBool( 'Tests', 'GridBlast', cboxGridBlast.Checked );
      Ini.WriteBool( 'Tests', 'GridBlastFP', cboxGridBlastFP.Checked );
      Ini.WriteBool( 'Tests', 'Fib', cboxFib.Checked );
      Ini.WriteBool( 'Tests', 'NBody', cboxNBody.Checked );
      Ini.WriteBool( 'Tests', 'PlotTrig', cboxPlotTrig.Checked );
      Ini.WriteBool( 'Tests', 'PlotTrig2', cboxTrig2.Checked );
      Ini.WriteBool( 'Tests', 'PlotLines', cboxPlotLines.Checked );
      Ini.WriteBool( 'Tests', 'RandomDots', cboxRandDots.Checked );
      Ini.WriteBool( 'Tests', 'RandomCircles', cboxRandomCircle.Checked );
      Ini.WriteBool( 'Tests', 'Mazes', cboxMaze.Checked );
      Ini.WriteBool( 'Tests', 'Fern', cboxFern.Checked );
      Ini.WriteBool( 'Tests', 'RichEd', cboxRichEd.Checked );
      Ini.WriteBool( 'Tests', 'CalculatePi', cboxCalculatePi.Checked );
      Ini.WriteBool( 'Tests', 'Dhrystone', cboxDhry.Checked );
      Ini.WriteBool( 'Tests', 'Whetstone', cboxWhet.Checked );
      Ini.WriteBool( 'Tests', 'MazeThreads', cboxMazeThreads.Checked );
      Ini.WriteBool( 'Tests', 'BandwidthBP64', cboxBandwidthBP64.Checked );
      Ini.WriteBool( 'Tests', 'MemLatency', cboxLatency.Checked );
      Ini.WriteBool( 'Tests', 'OThreads', cboxOThreads.Checked );
      Ini.WriteBool( 'Tests', 'IThreads', cboxIThreads.Checked );
      Ini.WriteBool( 'Tests', 'JpgDecode', cboxJpgDecode.Checked );
      Ini.WriteBool( 'Tests', 'ImageResize', cboxImageResize.Checked );
      Ini.WriteBool( 'Tests', 'ImageRotate', cboxImageRotate.Checked );
      Ini.WriteBool( 'Tests', 'Mp3Encode', cboxMp3Encode.Checked );
      Ini.WriteBool( 'Tests', 'WebPageLoad', cboxWebPageLoad.Checked );
      Ini.WriteBool( 'Tests', 'ZipCompress', cboxZipCompress.Checked );
      Ini.WriteBool( 'Tests', 'EncryptDecrypt', cboxEncryptDecrypt.Checked );
      Ini.WriteBool( 'Tests', 'FileCopy', cboxFileCopy.Checked );
      Ini.WriteBool( 'Tests', 'Lorenz', cboxLorenz.Checked );
      Ini.WriteBool( 'Tests', 'NBodyOpenGL', cboxNBodyOpenGL.Checked );
      Ini.WriteBool( 'Tests', 'DhrystoneThreadTest', cboxDhrystoneThreads.Checked );
      Ini.WriteBool( 'Tests', 'WhetstoneThreadTest', cboxWhetstoneThreads.Checked );
      Ini.WriteBool( 'Tests', 'PiThreadTest', cboxPiThreads.Checked );
      Ini.WriteBool( 'Tests', 'MandelbrotTest', cboxMandelbrot.Checked );
      Ini.WriteBool( 'Tests', 'EllipsesTest', cboxEllipses.Checked );
      Ini.WriteBool( 'Tests', 'RectanglesTest', cboxRectangles.Checked );
      Ini.WriteBool( 'Tests', 'LinesTest', cboxLines.Checked );
      Ini.WriteBool( 'Tests', 'FibThreadsTest', cboxFibThreads.Checked );
      Ini.WriteBool( 'Tests', 'PngOutThreadsTest', cboxPngOut.Checked );
      Ini.WriteBool( 'Tests', '7zipThreadsTest', cbox7zip.Checked );
      Ini.WriteBool( 'Tests', 'UpxThreadsTest', cboxUpx.Checked );
    except
      ShowMessage( 'An error occurred while trying to write to the INI file.' );
    end; // try...except
  finally
    FreeAndNil( Ini );
  end; // try..finally
end;// procedure TfrmOSMark.WriteIniFile;

procedure TfrmOSMark.FormCreate(Sender: TObject);
begin
  fbOfficialRun := FALSE;
  Left := 0; Top := 0;
  Caption := Caption + ', Version ' + Version;
  SetPriority;
  fStopWatch := TStopWatch.Create;
  fStopWatch.Resolution := swresHigh;
  fSystemInfo := TSystemInfo.Create( self );
  fSystemInfo.ShowStatus := TRUE;
  fSystemInfo.StopWatch := fStopWatch;
  fSystemInfo.Initialize;
  memoResults.Lines.Add( 'COSBI OSMark Version ' + Version );
  memoResults.Lines.Add( 'Date: ' + DateTimeToStr( Now ) );
  memoResults.Lines.Add( fSystemInfo.GetSystemSummary );
  memoResults.Lines.Add( '' );
  ReadIniFile;
  memoResults.Lines.Add( 'Ready.' );
  fbCommandLineRun := FALSE;
  Timer1.Enabled := TRUE;
end;

procedure TfrmOSMark.ParseCommandLine;
var
  i                   : integer;
  lbOfficialRun       : Boolean;
  lbRun               : Boolean;
  lbDefrag            : Boolean;
  lbProcessIdleTasks  : Boolean;
  lbSave              : Boolean;
  lbShowStatus        : Boolean;
  lbSpinUp            : Boolean;
  lbExit              : Boolean;
  lbAbort             : Boolean;
  liIterations        : integer;
  lsSaveFileName      : string;
  ldTime              : double;
  ldSeconds           : double;

  procedure InitializeLocalVariables;
  begin
    i := 1;
    lbRun  := FALSE;
    lbOfficialRun := FALSE;
    lbSave := FALSE;
    lbDefrag := FALSE;
    lbShowStatus := FALSE;
    lbSpinUp := FALSE;
    lbExit  := FALSE;
    lbProcessIdleTasks := FALSE;
    liIterations := 1;
    lsSaveFileName := DEFAULT_FILENAME;
    lbAbort := FALSE;
  end; // InitializeLocalVariables

  procedure InitializeOSMarkTestSuiteCL;
  begin
    fOSMarkTestSuite.Initialize( fSystemInfo );
    fOSMarkTestSuite.ShowStatus := lbShowStatus;
    fOSMarkTestSuite.SpinUp := lbSpinUp;
    fOSMarkTestSuite.ProcessIdleTasks := FALSE;
    fOSMarkTestSuite.DiskDefrag := FALSE;
    fOSMarkTestSuite.TargetDisk := DriveComboBoxTarget.Drive;
    LinkEventHandlers;
  end; // InitializeOSMarkTestSuiteCL;

  procedure DoParse;
  begin
    // parse commandline:
    while i <= ParamCount do begin
      if LowerCase( ParamStr(i) ) = 'or' then begin
        lbOfficialRun := TRUE;
      end else if LowerCase( ParamStr(i) ) = 'r' then begin
        lbRun := TRUE;
      end else if LowerCase( ParamStr(i) ) = 'i' then begin
        inc( i );
        liIterations := StrToInt( ParamStr( i ) );
      end else if LowerCase( ParamStr(i) ) = 'defrag' then begin
        lbDefrag := TRUE;
      end else if LowerCase( ParamStr(i) ) = 'pit' then begin
        lbProcessIdleTasks := TRUE;
      end else if LowerCase( ParamStr(i) ) = 'fn' then begin
        i := i + 1;
        lbSave := TRUE;
        lsSaveFileName := ParamStr( i );
      end else if LowerCase( ParamStr(i) ) = 'su' then begin
        lbSpinUp := TRUE;
      end else if LowerCase( ParamStr(i) ) = 's' then begin
        lbSave := TRUE;
      end else if LowerCase( ParamStr(i) ) = 'ss' then begin
        lbShowStatus := TRUE;
      end else if LowerCase( ParamStr(i) ) = 'e' then begin
        lbExit := TRUE;
      end else begin
        ShowMessage( 'Commandline parameters: or = official run;' + CR_LF +
          'r = run tests specified in ini file (will be ignored if "or" is specified); ' + CR_LF +
          'defrag = defrag disk; pit = process idle tasks; su = spin up cpu;' + CR_LF +
          'e = exit after run; i nnnn = iterate nnnn times' + CR_LF +
          's = save result memo to file' + CR_LF +
          'ss = Show status window between tests; fn "filename" = output filename' );
        lbAbort := TRUE;
      end; // if
      i := i + 1;
    end; // while
  end; // DoParse

begin
  if ParamCount < 1 then exit;
  fbCommandLineRun := TRUE;
  InitializeLocalVariables;
  DoParse;
  if lbAbort then begin
    application.Terminate;
    application.ProcessMessages;
    exit;
  end; // if
  // process command line selections:
  if lbDefrag then begin
    Defrag;
  end;
  if lbProcessIdleTasks then begin
    ProcessIdleTasks;
  end;
  fTestStart := Now;
  StatusBar1.Panels[ PANEL_TIME ].Text := 'Test starts: ' +
    DateTimeToStr( fTestStart );
  for i := 1 to liIterations do begin
    if lbOfficialRun then begin
      StatusBar1.Panels[ PANEL_LOOP ].Text :=
        'Loop ' + IntToStr( i ) + ' of ' + IntToStr( liIterations );
      fbOfficialRun := TRUE;
      fOSMarkTestSuite := TOSMarkTestSuite.Create( self );
      try
        InitializeOSMarkTestSuiteCL;
        fOSMarkTestSuite.OfficialRun;
      finally
        freeAndNil( fOSMarkTestSuite );
      end; // try...finally
      fbOfficialRun := FALSE;
    end else if lbRun then begin
      StatusBar1.Panels[ PANEL_LOOP ].Text :=
        'Loop ' + IntToStr( i ) + ' of ' + IntToStr( liIterations );
      fOSMarkTestSuite := TOSMarkTestSuite.Create( self );
      try
        InitializeOSMarkTestSuiteCL;
        fOSMarkTestSuite.RunTheseTests(GetSelectedTests, 1);
        Application.ProcessMessages;
      finally
        freeAndNil(   fOSMarkTestSuite );
      end; // try...finally
    end; // if lbOfficialRun
  end; // for
  ldTime := ( Now - fTestStart );
  ldSeconds := 24 * 60 * 60 * ldTime;
  StatusBar1.Panels[ PANEL_TIME ].Text := 'Run time (s): ' +
    FloatToStr( ldSeconds );
  application.ProcessMessages;
  if lbSave then begin
    SaveStringListToFile(memoResults.Lines , lsSaveFileName, FALSE);
  end; // if lbSave
  if lbExit then begin
    application.Terminate;
  end else begin
    fbCommandLineRun := FALSE;
  end;
end; // procedure TfrmOSMark.ParseCommandLine;


procedure TfrmOSMark.FormDestroy(Sender: TObject);
begin
  fStopWatch.Free;
end;

procedure TfrmOSMark.RunTests;
var
  liIterate : integer;
  lSelectedTests : TQTestSet;
begin
  liIterate := GetIterations;
  if liIterate < 1 then begin
    showmessage( 'Invalid choice for iterations: ' + IntToStr( liIterate ) );
    exit;
  end; // if
  lSelectedTests := GetSelectedTests;
  if lSelectedTests = [] then begin
    ShowMessage( 'You did not select any tests to run!' );
    exit;
  end; // if
  RunSelectedTests(liIterate, lSelectedTests);
end; // procedure TfrmOSMark.RunTests;

procedure TfrmOSMark.RunSelectedTests( aiInterate : integer;
                                       aSelectedTests: TQTestSet );
begin
  fOSMarkTestSuite := TOSMarkTestSuite.Create( self );
  try
    InitializeOSMarkTestSuite;
    fOSMarkTestSuite.RunTheseTests(aSelectedTests, aiInterate);
    Application.ProcessMessages;
  finally
    freeAndNil(   fOSMarkTestSuite );
  end; // try...finally
end; // procedure TfrmOSMark.RunSelectedTests

procedure TfrmOSMark.InitializeOSMarkTestSuite;
begin
  fOSMarkTestSuite.Initialize( fSystemInfo );
  fOSMarkTestSuite.ShowStatus := fbShowStatus;  //cboxStatus.Checked;
  fOSMarkTestSuite.SpinUp := fbSpinUp;   //cboxSpinUp.Checked;
  fOSMarkTestSuite.ProcessIdleTasks := fbProcessIdleTasks; //cboxProcessIdleTasks.Checked;
  fOSMarkTestSuite.DiskDefrag := fbDefragDrive; //cboxDefragDrive.Checked;
  fOSMarkTestSuite.TargetDisk := DriveComboBoxTarget.Drive;
  LinkEventHandlers;
end; // procedure TfrmOSMark.InitializeOSMarkTestSuite;

procedure TfrmOSMark.btnRunClick(Sender: TObject);
begin
  RunTests;
end; // procedure TfrmOSMark.btnRunClick(Sender: TObject);

procedure TfrmOSMark.btnSelectAllClick(Sender: TObject);
begin
  CheckUncheckBoxes(TRUE);
end;

procedure TfrmOSMark.btnSelectNoneClick(Sender: TObject);
begin
  CheckUncheckBoxes(FALSE);
end;

procedure TfrmOSMark.CheckUncheckBoxes(ab_Checked : Boolean);
var
  i : integer;
  ChildControl : TControl;
begin
  for i := 0 to gbSelectTests.ControlCount - 1 do begin
    ChildControl := gbSelectTests.Controls[ i ];
    if ChildControl.ClassName = 'TCheckBox' then begin
      TCheckBox( ChildControl ).Checked := ab_Checked;
    end; // if
  end; // for
end; //procedure TfrmOSMark.ChechUncheckBoxes

procedure TfrmOSMark.ClearOutput;
begin
  frmOutput.PaintBoxOutput.Buffer.Clear(clBlack32);
  frmOutput.PaintBoxOutput.Invalidate;
  Application.ProcessMessages;
end;

function TfrmOSMark.CountTests: integer;
var
  i : integer;
  ChildControl : TControl;
begin
  result := 0;
  for i := 0 to gbSelectTests.ControlCount - 1 do begin
    ChildControl := gbSelectTests.Controls[ i ];
    if ChildControl.ClassName = 'TCheckBox' then begin
      inc( result );
    end; // if
  end; // for
end; // function  TfrmCPUTests.CountTests

procedure TfrmOSMark.radioLowClick(Sender: TObject);
begin
  if radioLow.Checked then begin
    fStopWatch.Resolution := swresLow;
  end else if radioHigh.Checked then begin
    fStopWatch.Resolution := swresHigh;
  end else if radioCPU.Checked then begin
    fStopWatch.Resolution := swresCPU;
  end; // if radioLow.Checked
end;

procedure TfrmOSMark.btnSaveClick(Sender: TObject);
begin
  SaveStringListViaFileBrowser( memoResults.Lines, DEFAULT_FILENAME );
end; // procedure TfrmOSMark.btnSaveClick(Sender: TObject);

procedure TfrmOSMark.radioRealtimePClick(Sender: TObject);
begin
  SetPriority;
end;

function TfrmOSMark.GetSelectedTests: TQTestSet;
begin
  result := [];
  if cboxFib.Checked then result := result + [qtFib];
  if cboxGridBlast.Checked then result := result + [qtGrid];
  if cboxGridBlastFP.Checked then result := result + [qtGridFP];
  if cboxNBody.Checked then result := result + [qtNBody];
  if cboxPlotLines.Checked then result := result + [qtPlotLines];
  if cboxPlotTrig.Checked then result := result + [qtPlotTrig];
  if cboxRandDots.Checked then result := result + [qtRandomDots];
  if cboxRandomCircle.Checked then result := result + [qtCircles];
  if cboxMaze.Checked then result := result + [qtMaze];
  if cboxTrig2.Checked then result := result + [qtPlotTrig2];
  if cboxFern.Checked then result := result + [qtFern];
  if cboxRichEd.Checked then result := result + [qtRichEd];
  if cboxCalculatePi.Checked then result := result + [qtPi];
  if cboxDhry.Checked then result := result + [qtDhrystone];
  if cboxWhet.Checked then result := result + [qtWhetstone];
  if cboxBandwidthBP64.Checked then result := result + [qtBandwidthBP64];
  if cboxLatency.Checked then result := result + [qtMemLatency];
  if cboxMazeThreads.Checked then result := result + [qtMazeThreads];
  if cboxOThreads.Checked then result := result + [qtOrthogonalThreads];
  if cboxIThreads.Checked then result := result + [qtIdenticalThreads];
  if cboxJpgDecode.Checked then result := result + [qtJpgDecode];
  if cboxImageResize.Checked then result := result + [qtImageResize];
  if cboxImageRotate.Checked then result := result + [qtImageRotate];
  if cboxMp3Encode.Checked then result := result + [qtMP3Encode];
  if cboxWebPageLoad.Checked then result := result + [qtWebPageLoad];
  if cboxZipCompress.Checked then result := result + [qtZipCompress];
  if cboxEncryptDecrypt.Checked then result := result + [qtEncryptDecrypt];
  if cboxFileCopy.Checked then result := result + [qtFileCopy];
  if cboxLorenz.Checked then result := result + [qtLorenz];
  if cboxNBodyOpenGL.Checked then result := result + [qtNBodyOpenGL];
  if cboxDhrystoneThreads.Checked then result := result + [qtDhrystoneThreads];
  if cboxWhetstoneThreads.Checked then result := result + [qtWhetstoneThreads];
  if cboxPiThreads.Checked then result := result + [qtPiThreads];
  if cboxMandelbrot.Checked then result := result + [qtMandelbrotThreads];
  if cboxEllipses.Checked then result := result + [qtDrawEllipses];
  if cboxRectangles.Checked then result := result + [qtDrawRectangles];
  if cboxLines.Checked then result := result + [qtDrawLines];
  if cboxFibThreads.Checked then result := result + [qtFibThreads];
  if cboxPngOut.Checked then result := result + [qtPngOut];
  if cbox7zip.Checked then result := result + [qt7zip];
  if cboxUpx.Checked then result := result + [qtUpx];
//  if cboxFPMultiply.Checked then result := result + [qtFPMultiply];
end; // function TfrmOSMark.GetSelectedTests: aQTSet;

procedure TfrmOSMark.CheckOfficialRunTests;
begin
  cboxFib.Checked := qtFib in OFFICIAL_RUN_TESTS;
  cboxGridBlast.Checked := qtGrid in OFFICIAL_RUN_TESTS;
  cboxGridBlastFP.Checked := qtGridFP in OFFICIAL_RUN_TESTS;
  cboxNBody.Checked := qtNBody in OFFICIAL_RUN_TESTS;
  cboxPlotLines.Checked := qtPlotLines in OFFICIAL_RUN_TESTS;
  cboxPlotTrig.Checked := qtPlotTrig in OFFICIAL_RUN_TESTS;
  cboxRandDots.Checked := qtRandomDots in OFFICIAL_RUN_TESTS;
  cboxRandomCircle.Checked := qtCircles in OFFICIAL_RUN_TESTS;
  cboxMaze.Checked := qtMaze in OFFICIAL_RUN_TESTS;
  cboxTrig2.Checked := qtPlotTrig2 in OFFICIAL_RUN_TESTS;
  cboxFern.Checked := qtFern  in OFFICIAL_RUN_TESTS;
  cboxRichEd.Checked := qtRichEd in OFFICIAL_RUN_TESTS;
  cboxCalculatePi.Checked := qtPi in OFFICIAL_RUN_TESTS;
  cboxDhry.Checked := qtDhrystone in OFFICIAL_RUN_TESTS;
  cboxWhet.Checked := qtWhetstone in OFFICIAL_RUN_TESTS;
  cboxBandwidthBP64.Checked := qtBandwidthBP64 in OFFICIAL_RUN_TESTS;
  cboxLatency.Checked := qtMemLatency in OFFICIAL_RUN_TESTS;
  cboxMazeThreads.Checked := qtMazeThreads in OFFICIAL_RUN_TESTS;
  cboxOThreads.Checked := qtOrthogonalThreads in OFFICIAL_RUN_TESTS;
  cboxIThreads.Checked := qtIdenticalThreads in OFFICIAL_RUN_TESTS;
  cboxJpgDecode.Checked := qtJpgDecode in OFFICIAL_RUN_TESTS;
  cboxImageResize.Checked := qtImageResize in OFFICIAL_RUN_TESTS;
  cboxImageRotate.Checked := qtImageRotate in OFFICIAL_RUN_TESTS;
  cboxMp3Encode.Checked := qtMP3Encode in OFFICIAL_RUN_TESTS;
  cboxWebPageLoad.Checked := qtWebPageLoad in OFFICIAL_RUN_TESTS;
  cboxZipCompress.Checked := qtZipCompress in OFFICIAL_RUN_TESTS;
  cboxEncryptDecrypt.Checked := qtEncryptDecrypt in OFFICIAL_RUN_TESTS;
  cboxFileCopy.Checked := qtFileCopy in OFFICIAL_RUN_TESTS;
  cboxLorenz.Checked := qtLorenz in OFFICIAL_RUN_TESTS;
  cboxNBodyOpenGL.Checked := qtNBodyOpenGL in OFFICIAL_RUN_TESTS;
  cboxDhrystoneThreads.Checked := qtDhrystoneThreads in OFFICIAL_RUN_TESTS;
  cboxWhetstoneThreads.Checked := qtWhetstoneThreads in OFFICIAL_RUN_TESTS;
  cboxPiThreads.Checked := qtPiThreads in OFFICIAL_RUN_TESTS;
  cboxMandelbrot.Checked := qtMandelbrotThreads in OFFICIAL_RUN_TESTS;
  cboxEllipses.Checked := qtDrawEllipses in OFFICIAL_RUN_TESTS;
  cboxRectangles.Checked := qtDrawRectangles in OFFICIAL_RUN_TESTS;
  cboxLines.Checked := qtDrawLines in OFFICIAL_RUN_TESTS;
  cboxFibThreads.Checked := qtFibThreads in OFFICIAL_RUN_TESTS;
  cboxPngOut.Checked := qtPngOut in OFFICIAL_RUN_TESTS;
  cbox7zip.Checked := qt7zip in OFFICIAL_RUN_TESTS;
  cboxUpx.Checked := qtUpx in OFFICIAL_RUN_TESTS;
//  if cboxFPMultiply.Checked then result := result + [qtFPMultiply];
end; // function TfrmOSMark.GetSelectedTests: aQTSet;

function TfrmOSMark.GetIterations: integer;
begin
  result := strToInt( cboIterations.text );
end; // function TfrmOSMark.GetIterations: integer;

procedure TfrmOSMark.btnResultsClick(Sender: TObject);
var
  lfrmResults : TfrmOSMResults;
begin
  lfrmResults := TfrmOSMResults.Create(self);
  try
    lfrmResults.LoadDefaultDatabase;
    lfrmResults.ShowModal;
  finally
    lfrmResults.Release;
    freeAndNil( lfrmResults );
  end; // try..finally
end; // procedure TfrmOSMark.btnResultsClick(Sender: TObject);

procedure TfrmOSMark.btnAboutClick(Sender: TObject);
var
  s : string;
begin
  MediaPlayerAbout.Previous;
  MediaPlayerAbout.Play;
  s := 'COSBI: Comprehensive Open Source Benchmarking Initiative' + CR_LF
    + 'Copyright (c) 2004 Van Smith' + CR_LF + CR_LF
    + 'This program is free software; you can redistribute it and/or' + CR_LF
    + 'modify it under the terms of the GNU General Public License' + CR_LF
    + 'as published by the Free Software Foundation; either version 2' + CR_LF
    + 'of the License, or (at your option) any later version.' + CR_LF
    + 'This program is distributed in the hope that it will be useful,' + CR_LF
    + 'but WITHOUT ANY WARRANTY; without even the implied warranty of' + CR_LF
    + 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the' + CR_LF
    + 'GNU General Public License for more details.' + CR_LF + CR_LF
    + 'You should have received a copy of the GNU General Public License' + CR_LF
    + 'along with this program; if not, write to the Free Software' + CR_LF
    + 'Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.' + CR_LF + CR_LF
    + 'The current web address of the GNU General Public License is:' + CR_LF
    + 'http://www.gnu.org/licenses/gpl.html' + CR_LF + CR_LF
    + 'You can contact the authors of this software at:' + CR_LF
    + 'cosbi@vanshardware.com' + CR_LF
    + 'See www.vanshardware.com or www.cosbi.org for more contact/project details.' + CR_LF + CR_LF
    + 'Special thanks to:' + CR_LF
    + 'Ray Lischner, Author of _Delphi in a Nutshell_, for code in TPiTest' + CR_LF
    + 'See www.tempest-sw.com for a look at some of Ray Lischner''s famous books.' + CR_LF
    + 'Bayu Prasetio for help with TWhetstone, TDhrystone, and more' + CR_LF
    + 'Chris Yeager for the much of the maze test'  + CR_LF
    + 'Vijay Hariharan, Tom and Kendra Crispin, CJ Holthaus, Kathy Smith' + CR_LF
    + 'Joel Hruska, Dave Graham and Richard Chetwood' + CR_LF + CR_LF
    + 'This program uses the Graphics32 library obtainable at:' + CR_LF
    + 'http://www.g32.org/' + CR_LF
    + 'The zip test utilizes ZipForge which can be obtained freely at:' + CR_LF
    + 'http://www.componentace.com/zip_component_zip_delphi_zipforge.htm' + CR_LF
    + 'GOGO-no-coda: http://homepage1.nifty.com/herumi/gogo_e.html' + CR_LF + CR_LF
    + 'PNGout: http://advsys.net/ken/utils.htm#pngout' + CR_LF + CR_LF
    + '7zip: http://www.7-zip.org/' + CR_LF + CR_LF
    + 'UPX: http://upx.sourceforge.net/' + CR_LF + CR_LF
    + 'OpenGL tests use the excellent GLScene open source component suite.' + CR_LF
    + 'COSBI is an organic project!  Submit your unique tests to:' + CR_LF
    + 'cosbi@vanshardware.com' + CR_LF + CR_LF
    + 'See http://rebelfirerock.com/ for more on "Justice Day".';
  ShowMessage( s );
  MediaPlayerAbout.Stop;
end;

procedure TfrmOSMark.btnCPUInfoClick(Sender: TObject);
var
  frmCPUInfo : TfrmCPUInfo;
begin
  frmCPUInfo := TfrmCPUInfo.Create( Self );
  with frmCPUInfo do begin
    try
      ShowModal;
    finally
      release;
      freeandnil( frmCPUInfo );
    end; // try
  end; // with
end;

procedure TfrmOSMark.BitBtnOfficialRunClick(Sender: TObject);
begin
  OfficialRun;
end;

procedure TfrmOSMark.OfficialRun;
var
  lfrmOSMResults : TfrmOSMResults;
begin
  fbOfficialRun := TRUE;
  cboIterations.ItemIndex := OFFICIAL_RUN_ITERATIONS - 1;
  CheckOfficialRunTests;
  fOSMarkTestSuite := TOSMarkTestSuite.Create( self );
  try
    InitializeOSMarkTestSuite;
    fOSMarkTestSuite.OfficialRun;
    lfrmOSMResults := TfrmOSMResults.Create(self);
    try
      lfrmOSMResults.OSMarkTestResults := fOSMarkTestSuite.OSMarkTestResults;
      lfrmOSMResults.ShowModal;
    finally
      lfrmOSMResults.Release;
      FreeAndNil( lfrmOSMResults );
    end;
  finally
    freeAndNil( fOSMarkTestSuite );
  end; // try...finally
  fbOfficialRun := FALSE;
end; // procedure TfrmOSMark.OfficialRun;

procedure TfrmOSMark.UpdateStatusMemo( Sender: TObject );
begin
  memoResults.Lines.Add( fOSMarkTestSuite.OutputString );
  application.processmessages;
end; // procedure UpdateStatusMemo( asOutputLine : string );

procedure TfrmOSMark.OnTestSuiteRunStart( Sender: TObject );
begin
  pBar.Progress := 0;
  pBar.MaxValue := fOSMarkTestSuite.TotalNumberOfTestsToRun;
  ClearStatusBar;
  if not fbCommandLineRun then begin
    fTestStart := Now;
    StatusBar1.Panels[ PANEL_TIME ].Text := 'Test starts: ' +
      DateTimeToStr( fTestStart );
  end; // if
end; // procedure TfrmOSMark.OnTestSuiteRunStart

procedure TfrmOSMark.OnIterationStart( Sender: TObject );
begin
  StatusBar1.Panels[ PANEL_ITERATION ].Text := 'Iteration ' +
    intToStr( fOSMarkTestSuite.Interation ) + ' of ' +
    intToStr( fOSMarkTestSuite.InterationFinal );
  application.processmessages;
end; //procedure OnIterationStart( Sender: TObject );

procedure TfrmOSMark.OnTestBegins( Sender: TObject );
begin
  StatusBar1.Panels[ PANEL_MAIN ].text := 'Running ' +
    fOSMarkTestSuite.TestName + '...';
  application.ProcessMessages;
end;

procedure TfrmOSMark.OnTestEnds( Sender: TObject );
begin
  pBar.Progress := pBar.Progress + 1;
  StatusBar1.Panels[ PANEL_MAIN ].text := '';
  StatusBar1.Panels[ PANEL_LAST_RESULT ].text := fOSMarkTestSuite.TestName +
    ' score = ' + IntToStr( fOSMarkTestSuite.TestScore );
  application.ProcessMessages;
end; // procedure OnTestEnds( Sender: TObject );

procedure TfrmOSMark.OnTestSuiteRunEnd( Sender: TObject );
var
  ldTime : double;
  ldSeconds : double;
begin
  pBar.Progress := pBar.MaxValue;
  StatusBar1.Panels[ PANEL_MAIN ].text := 'Test Complete. Ready...';
  if not fbCommandLineRun then begin
    ldTime := ( Now - fTestStart );
    ldSeconds := 24 * 60 * 60 * ldTime;
    StatusBar1.Panels[ PANEL_TIME ].Text := 'Run time (s): ' +
      FloatToStr( ldSeconds );
    application.ProcessMessages;
  end; // if
end; // procedure OnTestEnds( Sender: TObject );

procedure TfrmOSMark.ClearStatusBar;
begin
  StatusBar1.Panels[ PANEL_MAIN ].Text := '';
  StatusBar1.Panels[ PANEL_LAST_RESULT ].Text := '';
  StatusBar1.Panels[ PANEL_ITERATION ].Text := '';
  if not fbCommandLineRun then StatusBar1.Panels[ PANEL_TIME ].Text := '';
end; //procedure TfrmOSMark.ClearStatusBar;

procedure TfrmOSMark.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  WriteIniFile;
end;

procedure TfrmOSMark.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := FALSE;
  application.ProcessMessages;
  ParseCommandLine;
end;

procedure TfrmOSMark.btnBandwidthBurnClick(Sender: TObject);
var
  SaveCursor : TCursor;
begin
  btnBandwidthBurn.Enabled := FALSE;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  try
    if assigned( frmBandwidthBurn ) then begin
      try
        frmBandwidthBurn.Show;
        exit;
      except
        frmBandwidthBurn := NIL;
      end; // try
    end;
    try
      if ( not assigned( frmBandwidthBurn ) ) or
         ( not frmBandwidthBurn.Visible ) then begin
        frmBandwidthBurn := TfrmCOSBIBandwidthBurn.Create( Self );
        frmBandwidthBurn.FreeOnClose := FALSE;
        frmBandwidthBurn.SystemInfo := fSystemInfo;
      end;
    finally
      frmBandwidthBurn.Show;
    end; //try...finally
  finally
    Screen.Cursor := SaveCursor;
    btnBandwidthBurn.Enabled := TRUE;
  end; // try..finally
end;

procedure TfrmOSMark.btnMemLatencyPlusClick(Sender: TObject);
var
  SaveCursor : TCursor;
begin
  btnMemLatencyPlus.Enabled := FALSE;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  try
    if ( not assigned( frmMemLatencyPlus ) ) or
       ( not frmMemLatencyPlus.Visible ) then begin
      if assigned( frmMemLatencyPlus ) then begin
        try
          FreeAndNil( frmMemLatencyPlus );
        except
          frmMemLatencyPlus := NIL;
        end; // try
      end; // if
      frmMemLatencyPlus := TfrmMemLate.Create( self );
      frmMemLatencyPlus.SystemInfo := fSystemInfo;
    end;
  finally
    frmMemLatencyPlus.Show;
    Screen.Cursor := SaveCursor;
    btnMemLatencyPlus.Enabled := TRUE;
  end; //try...finally
end;

procedure TfrmOSMark.btnFileCopyClick(Sender: TObject);
var
  SaveCursor : TCursor;
begin
  btnFileCopy.Enabled := FALSE;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  try
    if ( not assigned( frmCopyFile ) ) or
       ( not frmCopyFile.Visible ) then begin
      if assigned( frmCopyFile ) then begin
        try
          FreeAndNil( frmCopyFile );
        except
          frmCopyFile := NIL;
        end; // try
      end; // if
      frmCopyFile := TfrmCopyFile.Create( self );
      frmCopyFile.SystemInfo := fSystemInfo;
    end;
  finally
    frmCopyFile.Show;
    Screen.Cursor := SaveCursor;
    btnFileCopy.Enabled := TRUE;
  end; //try...finally
end;

procedure TfrmOSMark.btnWhetBurnClick(Sender: TObject);
var
  SaveCursor : TCursor;
begin
  btnWhetBurn.Enabled := FALSE;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  try
    if ( not assigned( frmWhetBurn ) ) or
       ( not frmWhetBurn.Visible ) then begin
      if assigned( frmWhetBurn ) then begin
        try
          FreeAndNil( frmWhetBurn );
        except
          frmWhetBurn := NIL;
        end; // try
      end; // if
      frmWhetBurn := TfrmWhetBurn.Create( self );
    end;
  finally
    frmWhetBurn.Show;
    Screen.Cursor := SaveCursor;
    btnWhetBurn.Enabled := TRUE;
  end; //try...finally
end;

procedure TfrmOSMark.btnCpuSpeedClick(Sender: TObject);
var
  SaveCursor : TCursor;
  lstrAppPath : string;
const
  CPU_SPEED_FILE = 'osmfiles\CPUSpeed.exe';
begin
  btnCpuSpeed.Enabled := FALSE;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  try
    lstrAppPath := ExtractFilePath(Application.ExeName);
    StartProgram( lstrAppPath + CPU_SPEED_FILE );
//    if ( not assigned( frmCPUSpeed ) ) or
//       ( not frmCPUSpeed.Visible ) then begin
//      if assigned( frmCPUSpeed ) then begin
//        try
//          FreeAndNil( frmCPUSpeed );
//        except
//          frmCPUSpeed := NIL;
//        end; // try
//      end; // if
//      frmCPUSpeed := TfrmCPUSpeed.Create( self );
//    end;
  finally
//    frmCPUSpeed.Show;
    Screen.Cursor := SaveCursor;
    btnCpuSpeed.Enabled := TRUE;
  end; //try...finally
end;

procedure TfrmOSMark.btnCpuUtilizationClick(Sender: TObject);
var
  SaveCursor : TCursor;
  lstrAppPath : string;
const
  CPU_UTILIZATION_FILE_COMMAND = 'osmfiles\CosbiCpuUtilization.exe';
begin
  btnCpuUtilization.Enabled := FALSE;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  try
    lstrAppPath := ExtractFilePath(Application.ExeName);
    StartProgram( lstrAppPath + CPU_UTILIZATION_FILE_COMMAND );
  finally
    Screen.Cursor := SaveCursor;
    btnCpuUtilization.Enabled := TRUE;
  end; //try...finally

//    if ( not assigned( frmCpuUtilization ) ) or
//       ( not frmCpuUtilization.Visible ) then begin
//      if assigned( frmCpuUtilization ) then begin
//        try
//          FreeAndNil( frmCpuUtilization );
//        except
//          frmCpuUtilization := NIL;
//        end; // try
//      end; // if
//      frmCpuUtilization := TfrmCpuUtilization.Create( self );
//      frmCpuUtilization.FormStyle := fsMDIForm;
//    end;
end;

procedure TfrmOSMark.btnThreadWreckerClick(Sender: TObject);
var
  lTest : TLaunchProgramThreadTest;
  lsAppPath : string;
  lsLorenzFilePath : string;
  lsNBodyFilePath : string;
  lsAesFilePath : string;
  lsGogoFilePath : string;
  liScore : integer;
begin
  memoResults.Lines.Add( 'Running "ThreadWrecker".' );
  lTest := TLaunchProgramThreadTest.Create;
  try
    lTest.StopWatch := fStopWatch;
    lsAppPath := ExtractFilePath( Application.ExeName );
    lsLorenzFilePath := lsAppPath + 'osmfiles\projectionLorenz.exe';
    lsAesFilePath := lsAppPath + 'osmfiles\AESBench.exe';
    lsGogoFilePath := lsAppPath + 'osmfiles\gogo.exe -test 600';
    lsNBodyFilePath := lsAppPath + 'osmfiles\nBody.exe';
    memoResults.Lines.Add( 'Spawning ' + lsGogoFilePath );
    lTest.ProgramCommand1 := lsGogoFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsAesFilePath );
    lTest.ProgramCommand2 := lsAesFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsLorenzFilePath );
    lTest.ProgramCommand3 := lsLorenzFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsNBodyFilePath );
    lTest.ProgramCommand4 := lsNBodyFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsGogoFilePath );
    lTest.ProgramCommand5 := lsGogoFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsAesFilePath );
    lTest.ProgramCommand6 := lsAesFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsGogoFilePath );
    lTest.ProgramCommand7 := lsGogoFilePath;
    memoResults.Lines.Add( 'Spawning ' + lsAesFilePath );
    lTest.ProgramCommand8 := lsAesFilePath;
    lTest.NbrOfThreadsToRun := 8;
    lTest.Run;
    liScore := lTest.GetScore(0);
    memoResults.Lines.Add( 'ThreadWrecker score' + TAB + intToStr( liScore ) );
    memoResults.Lines.Add( 'ThreadWrecker time (s)' + TAB + lTest.GetFormattedMinTime );
  finally
    freeAndNil( lTest );
  end; // try...finally
end;

procedure TfrmOSMark.BitBtnMobileClick(Sender: TObject);
const
  FOREVER = FALSE;
var
  ldPerformanceScore : double;
  ldBatteryLifeScore : double;
  ldMobileScore : double;
  lStopWatch : TStopWatch;
  ldRunStart : double;
  lqtTest : TQTests;
  leRunTime : extended;

  procedure MobileOfficialRun;
  begin
    fbOfficialRun := TRUE;
    cboIterations.ItemIndex := OFFICIAL_RUN_ITERATIONS - 1;
    CheckOfficialRunTests;
    fOSMarkTestSuite := TOSMarkTestSuite.Create( self );
    try
      InitializeOSMarkTestSuite;
      fOSMarkTestSuite.OfficialRun;
      ldPerformanceScore := 1000 *
        fOSMarkTestSuite.OSMarkTestResults.GetCosbiScore( FALSE ) /
        REFERENCE_NB_PERFORMANCE_SCORE;
    finally
      freeAndNil( fOSMarkTestSuite );
    end; // try...finally
    fbOfficialRun := FALSE;
  end; // procedure MobileOfficialRun;

  procedure ComputeScore;
  begin
    // calculate battery life score:
    leRunTime := lStopWatch.SplitTime;
    if cboxMaxPowerDraw.Checked then begin
      ldBatteryLifeScore := ( leRunTime / REFERENCE_NB_RUNDOWN_MAX_POWER_TIME ) * 1000;
    end else begin
      ldBatteryLifeScore := ( leRunTime / REFERENCE_NB_RUNDOWN_TIME ) * 1000;
    end;
    ldMobileScore := (ldPerformanceScore + ldBatteryLifeScore) / 2;
  end;

  procedure OutputScore;
  begin
    memoResults.Lines.Add( '');
    memoResults.Lines.Add( '**********');
    if cboxMaxPowerDraw.Checked then begin
      memoResults.Lines.Add( 'Max Power Battery depletion time ' + TAB + FloatToStrF(leRunTime / 60, ffNumber,6, 3) + ' minutes' );
      memoResults.Lines.Add( 'Performance score ' + TAB +  FloatToStrF( ldPerformanceScore, ffNumber,6, 3) );
      memoResults.Lines.Add( 'Max Power Battery life score ' + TAB + FloatToStrF( ldBatteryLifeScore, ffNumber,6, 3) );
      memoResults.Lines.Add( 'OVERALL MAX POWER MOBILE SCORE ' + TAB + FloatToStrF( ldMobileScore, ffNumber,6, 3) );
    end else begin
      memoResults.Lines.Add( 'Battery depletion time ' + TAB + FloatToStrF(leRunTime / 60, ffNumber,6, 3) + ' minutes' );
      memoResults.Lines.Add( 'Performance score ' + TAB +  FloatToStrF( ldPerformanceScore, ffNumber,6, 3) );
      memoResults.Lines.Add( 'Battery life score ' + TAB + FloatToStrF( ldBatteryLifeScore , ffNumber,6, 3) );
      memoResults.Lines.Add( 'OVERALL MOBILE SCORE ' + TAB + FloatToStrF( ldMobileScore , ffNumber,6, 3) );
  end;
  end; // OutputScore;

  procedure UpdateScore;
  begin
    ComputeScore;
    OutputScore;
    SaveStringListToFile( memoResults.Lines, DEFAULT_MOBILE_FILENAME, FALSE, TRUE );
  end;

  procedure SleepForAwhile;
  begin
    memoResults.Lines.Add( '' );
    memoResults.Lines.Add( 'Sleeping for 1 minute between tests...' );
    sleep( 1000 * 60 );
  end;

begin
  // we don't need to defrag or process idle tasks since that can take hours on
  // a notebook.
  cboxProcessIdleTasks.Checked := FALSE;
  cboxDefragDrive.Checked := FALSE;
  // initialize scores:
  ldPerformanceScore := 0;
  ldBatteryLifeScore := 0;
  ldMobileScore := 0;
  // tell the user to unplug the notebook:
  ShowMessage( 'Before continuing, make sure that the screensaver is turned off.' + CR_LF +
    'Also, from "Power Options Properties" opened from the Display Properties|Screen Saver tab' + CR_LF +
    'set the monitor to never turn off when running on batteries, but turn off hard disks at 3 minutes.' + CR_LF +
    'From the same tab, the system should never enter standby when on batteries.' + CR_LF +
    'On the "Alarms" tab, uncheck "Low battery alarm," but check "Critical battery alarm."' + CR_LF +
    'Set the critical battery alarm to go off when the power level is at 3%.' + CR_LF +
    'The alarm action needs to be "Shut down" and the alarm should force the shutdown' + CR_LF +
    'if a program stops responding.' + CR_LF + CR_LF +
    'The test will run until the battery is exhausted.  Upon reconnecting power and restarting' + CR_LF +
    'the notebook, the mobile results can be found at the end of the file "OSMarkMobileResults.txt".' + CR_LF + CR_LF +
    'Once the tests are underway, you can press <Esc> to abort them if necessary.' + CR_LF + CR_LF +
    'When ready, please disconnect the power adapter from the notebook and then press <Enter>.' );
  // The mobile score is composed of two components: an official run for
  // performance and a battery run down cycle.
  // When the mobile run is issued, it starts with an official performance
  // run.  The OpenSourceMark score is retained while OSMark tests are then
  // issued spaced one minute apart until the battery is depleted.

  lStopWatch := TStopWatch.Create;
  try
    lStopWatch.Resolution := swresHigh;
    // we need to time how long the system is running:
    lStopWatch.StartTimer;
    if cboxMaxPowerDraw.Checked then begin
      // turn off the status window to remove dead time:
      cboxStatus.Checked := FALSE;
      fbShowStatus := FALSE;
    end else begin
      // turn on status window for normal battery drain tests:
      cboxStatus.Checked := TRUE;
      fbShowStatus := TRUE;
    end; //if
    // Issue an official run:
    MobileOfficialRun;
    UpdateScore;
    StatusBar1.Panels[ PANEL_MAIN ].text := 'Running battery depletion tests...';
    application.ProcessMessages;
    // there is no need to spin up prior to tests for battery drain measurement:
    fbSpinUp := FALSE;
    if cboxMaxPowerDraw.Checked then begin
      // turn off the status window to remove dead time:
      fbShowStatus := FALSE;
    end else begin
      // turn on status window for normal battery drain tests:
      fbShowStatus := TRUE;
    end; //if

    // we need to run tests spaced at on minute apart until the battery runs down:
    repeat
      for lqtTest in OFFICIAL_RUN_TESTS do begin
        RunSelectedTests( 1 , [lqtTest] );
        // write out score
        UpdateScore;
        // on normal test, sleep for a minute between tests, otherwise proceed to
        // next test:
        if not cboxMaxPowerDraw.Checked then begin
          // wait one minute
          StatusBar1.Panels[ PANEL_MAIN ].text := 'Running battery depletion tests...';
          application.ProcessMessages;
          SleepForAwhile;
        end; // if
      end; // for
    until FOREVER;
  finally
    freeAndNil( lStopWatch );
  end; // try
end;

procedure TfrmOSMark.BitBtnThinClientClick(Sender: TObject);
begin
  ShowMessage( 'Special thin client benchmark coming in release version.' );
end;

procedure TfrmOSMark.cboxSpinUpClick(Sender: TObject);
begin
  fbSpinUp := cboxSpinUp.Checked;
end;

procedure TfrmOSMark.cboxStatusClick(Sender: TObject);
begin
  fbShowStatus := cboxStatus.Checked;
end;

procedure TfrmOSMark.cboxProcessIdleTasksClick(Sender: TObject);
begin
  fbProcessIdleTasks := cboxProcessIdleTasks.Checked;
end;

procedure TfrmOSMark.cboxDefragDriveClick(Sender: TObject);
begin
  fbDefragDrive := cboxDefragDrive.Checked;
end;

procedure TfrmOSMark.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = KEY_ESC then begin
    halt;
  end;
end;

procedure TfrmOSMark.BitBtnOfficialRunKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = KEY_ESC then begin
    halt;
  end;
end;

procedure TfrmOSMark.BitBtnQuitClick(Sender: TObject);
begin
  halt;
end;

end.
