unit uLight;

interface

uses Classes, SysUtils, GR32, Dialogs, Graphics;

type TLight = class
private
        idxStream, mulStream: TMemoryStream;
public
        loaded: Boolean;
        constructor Create;
        destructor Free;
        procedure Load( idxPath, mulPath : String );
        procedure Save( idxPath, mulPath : String );
        function Count : Integer;
        function Exists( Id : Integer ) : Boolean;
        function GetLight( Id : Integer ) : TBitmap32;
        procedure LoadLight( Id : Integer; FilePath : String );
end;

var     Light : TLight;

implementation

uses uUtilities, StrLib, uGaugeForm;

type    TIndexRecord = packed record
                Offset: Integer;
                Length: Integer;
                Extra: Integer
        end;

constructor TLight.Create;
begin
        idxStream := TMemoryStream.Create;
        mulStream := TMemoryStream.Create;
        loaded := False;
end;

destructor TLight.Free;
begin
        idxStream.Free;
        mulStream.Free;
end;

procedure TLight.Load( idxPath, mulPath : String );
begin
        idxStream.LoadFromFile( idxPath );
        mulStream.LoadFromFile( mulPath );
        loaded := true;
end;

procedure TLight.Save( idxPath, mulPath : String );
begin
        idxStream.SaveToFile( idxPath );
        mulStream.SaveToFile( mulPath );
end;

function TLight.Count : Integer;
begin
        Result := idxStream.Size div 12;
end;

function TLight.Exists( Id : Integer ) : Boolean;
var     IndexRec : TIndexRecord;
begin
        idxStream.Seek( Id*12, soFromBeginning );
        idxStream.Read( IndexRec, sizeof( TIndexRecord ) );

        if ( IndexRec.Offset <> -1 ) and ( IndexRec.Length <> -1 ) and ( IndexRec.Extra <> -1 ) then
                Result := true
        else
                Result := False;
end;

function TLight.GetLight( Id : Integer ) : TBitmap32;
var     Hoehe, Breite : Integer;
        IndexRec : TIndexRecord;
        x, y : Integer;
        Color : Byte;
        Red, Blue, Green : Integer;
begin
        idxStream.Seek( Id*12, soFromBeginning );
        idxStream.Read( IndexRec, sizeof( TIndexRecord ) );

        Breite := IndexRec.Extra shr 16;
        Hoehe := IndexRec.Extra and $FFFF;

        mulStream.Seek( IndexRec.Offset, soFromBeginning );

        Result := TBitmap32.Create;
        Result.SetSize( Breite, Hoehe );

        for y := 0 to Hoehe-1 do begin
                for x := 0 to Breite-1 do begin
                        mulStream.Read( Color, 1 );
                        Red := Color;
                        Green := Color;
                        Blue := Color;
                        if Color <> 0 then
                                Result.Pixel[x,y] := Color32( Red, Green, Blue )
                        else
                                Result.Pixel[x,y] := Color32( 0, 255, 0 );
                end;
        end;
end;

procedure TLight.LoadLight( Id : Integer; FilePath : String );
var     Bitmap : TBitmap32;
        Red : Byte;
        Breite, Hoehe : Word;
        x, y : Integer;
        IndexRec : TIndexRecord;
        Invis : TColor32;
begin
        Bitmap := TBitmap32.Create;
        Bitmap.LoadFromFile( FilePath );

        Breite := Bitmap.Width;
        Hoehe := Bitmap.Height;
        Invis := Color32( 0, 255, 0 );

        mulStream.Seek( 0, soFromEnd );
        IndexRec.Offset := mulStream.Position;
        IndexRec.Extra := ( Breite shl 16 ) + Hoehe;

        for y := 0 to Hoehe-1 do begin
                for x := 0 to Breite-1 do begin
                        if Bitmap.Canvas.Pixels[x,y] <> Invis then begin
                                Red := RedComponent( Bitmap.Canvas.Pixels[x,y] );
                                mulStream.Write( Red, 1 );
                        end
                        else begin
                                Red := 0;
                                mulStream.Write( Red, 1 );
                        end;
                end;
        end;

        IndexRec.Length := mulStream.Position - IndexRec.Offset;

        idxStream.Seek( Id*12, soFromBeginning );
        idxStream.Write( IndexRec, sizeof( TIndexRecord ) );
end;

end.
