program a1;

uses
  Forms,
  windows,
  registry,
  sysutils,
  controls,
  a1_u in 'a1_u.pas' {mainForm},
  vectors in '..\..\..\..\..\delphikomp\vectors.pas',
  Spheres in 'Spheres.pas',
  farbe in 'farbe.pas' {colorManager},
  memory in '..\..\..\..\..\delphikomp\memory.pas',
  statistik_u in 'statistik_u.pas' {statsForm},
  threeD in 'threeD.pas' {threeDForm},
  Spheres3D in 'Spheres3D.pas',
  ExtraListView in 'ExtraListView.pas',
  helpWindow in 'helpWindow.pas' {help};

{$R *.RES}

//Setzt die übergebene Bildschirmauflösung mit den angegeben Flags
function simpleChangeDisplay(const screenW,screenH,flags:dword):integer;
var devMode:TDevMode;
begin
  ZeroMemory(@devmode,sizeof(devmode));
  devMode.dmSize:=sizeof(devmode);
  devMode.dmPelsWidth:=screenW;
  devMode.dmPelsHeight:=screenH;
  devMode.dmFields:=DM_PELSWIDTH or DM_PELSHEIGHT;
  result:=ChangeDisplaySettings(devMode,flags);
end;
//Computer neustarten
procedure reboot;
var
  token:THandle;
  Privileges,temp:_TOKEN_PRIVILEGES;
  tempc:cardinal;
begin
  if Win32Platform=VER_PLATFORM_WIN32_NT	 then begin
    //Rechte zum Herunterfahren holen, sonst darf man es bei NT/2000/XP nicht
    OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES,token);
    Privileges.PrivilegeCount:=1;
    LookupPrivilegeValue(nil,'SeShutdownPrivilege',Privileges.Privileges[0].Luid);
    Privileges.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(token,false,Privileges,sizeof(Privileges),temp,tempc);
    CloseHandle(token);
  end;
  ExitWindowsEx(EWX_REBOOT,0); //Neustarten
end;

var displayInfo:integer;
    oldScreenWidth,oldScreenHeight:integer;
    reg:TRegistry;
begin
  Application.Initialize;
  if (screen.Width<1024) or (screen.Height<768) then begin
    //Aktuelle Bildschirmauflösung sichern
    oldScreenWidth:=screen.Width;
    oldScreenHeight:=screen.Height;
    //Feststellen ob die Auflösung unterstütz wird
    displayInfo:=simpleChangeDisplay(1024,768,CDS_TEST);
    //Geht sie nicht?
    if (displayInfo=DISP_CHANGE_BADMODE) or (displayInfo=DISP_CHANGE_FAILED) then begin
      Application.MessageBox(pchar('Dieses Programm läuft nur mit einer Mindestauflösung'+
                             'von 1024x768 Pixeln. Diese Auflösung wird aber von'+
                             'ihrem Computer nicht unterstützt, am besten besorgen'+
                             'Sie sich einen neuen Bildschirm bzw. Computer.'+
                             'Für Risiken oder Nebenwirkungen einer höheren Bildschirmauflösung'+
                             'fragen sie bitte ihren Arzt oder Techniker'),
                             'Kugelsimulator (Aufgabe 1)', MB_OK or MB_TOPMOST or MB_ICONERROR);
      exit;
    end;
    //Muss vor dem Wechsel neugestartet werden?
    if (displayInfo=DISP_CHANGE_RESTART) then begin
      if Application.MessageBox(pchar('Dieses Programm läuft nur mit einer Mindestauflösung'+
                              'von 1024x768 Pixeln. Ihre Auflösung beträgt aber '+
                              intToStr(screen.Width)+'x'+ intToStr(screen.Height)+
                              '. Soll die Bildschirmauflösung umgestellt werden?'+
                              ' (Dazu muss ihr Computer neugestartet werden'),
                              'Kugelsimulator (Aufgabe 1)',MB_YESNO or MB_ICONWARNING)=ID_YES then begin
       //In der Registry eintragen
       simpleChangeDisplay(1024,768,CDS_UPDATEREGISTRY);
       //Beim nächsten (aber nur beim nächsten) Windowstart automatisch starten
       reg:=TRegistry.create;
       try
         reg.RootKey:=HKEY_CURRENT_USER;
         reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Runonce',true);
         //Als Parameter die Standardauflösung
         reg.WriteString('Kugelsimulator',ParamStr(0)+' '+IntToStr(oldScreenWidth)+'|'+inttostr(oldScreenHeight));
         reg.CloseKey;
       finally
         reg.free;
       end;
       reboot;
      end;
      exit;
    end else
      //Kann sie ohne Probleme gewechselt werden?
      if Application.MessageBox(pchar('Dieses Programm läuft nur mit einer Mindestauflösung'+
                              'von 1024x768 Pixeln. Ihre Auflösung beträgt aber '+
                              intToStr(screen.Width)+'x'+ intToStr(screen.Height)+
                              '. Soll die Bildschirmauflösung umgestellt werden?'),
                              'Kugelsimulator (Aufgabe 1)',MB_YESNO or MB_ICONQUESTION)=ID_YES then
      simpleChangeDisplay(1024,768,0) //einfach wechseln
      else exit;
  end else //Richtige Auflösung?
    if ParamStr(1)<>'' then begin //Gibt es ein alte Auflösung die wiederhergrestellt
                                  //werden soll
      oldScreenWidth:=StrToInt(GetShortHint(ParamStr(1)));
      oldScreenHeight:=StrToInt(GetLongHint(ParamStr(1)));
    end else begin
      oldScreenWidth:=-1;
      oldScreenHeight:=-1;
    end;

  //Standard VCL
  Application.Title := 'Kugelsimulation';
  Application.CreateForm(TmainForm, mainForm);
  Application.CreateForm(TcolorManager, colorManager);
  Application.CreateForm(TstatsForm, statsForm);
  Application.CreateForm(TthreeDForm, threeDForm);
  Application.CreateForm(Thelp, help);
  Application.Run;

  //Gibt es ein alte Auflösung die wiederhergrestellt werden soll
  if oldScreenWidth<>-1 then begin
    displayInfo:=simpleChangeDisplay(oldScreenWidth,oldScreenHeight,CDS_TEST);
    if displayInfo=DISP_CHANGE_RESTART then begin //muss neugestartet werden?
      //Wechseln und neustarten
      simpleChangeDisplay(oldScreenWidth,oldScreenHeight,CDS_UPDATEREGISTRY);
      reboot;
    end else simpleChangeDisplay(oldScreenWidth,oldScreenHeight,0); //einfach wechseln
  end;
end.
