//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "UnitVideoDemo.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

//---------------------------------------------------------------------------
__fastcall TFormVideoDemo::TFormVideoDemo(TComponent* Owner, AnsiString Caption): TForm(Owner)
{
	hdd = DrawDibOpen();
	LastFrame = NULL;
	LastWidth = Width;
	LastHeight = Height;
	LastLeft = Left;
	LastTop = Top;
	if (Caption != "")
	{
		this->Caption = Caption;
	}
	FCaption = this->Caption;
	FOutputAspectRatio = 0;
//	Label1->Caption = "\n\n\nREALTIME\n\nAutomatic Editing\nof Lectures";
//	Label1->Caption = "\n\n\nREALTIME\n\nAutomatic Video Editing";
//	PanelRight->Visible = false;
	FFullScreen = false;
	SourceSlides = NULL;
	FSlideCount = 0;
	FSlideAspectRatio = 4.0 / 3.0;
	ImageIndex = 0;
	FLastImage = NULL;
}

//---------------------------------------------------------------------------
__fastcall TFormVideoDemo::~TFormVideoDemo()
{
	if (hdd)
	{
		DrawDibClose(hdd);
	}
}

//---------------------------------------------------------------------------
void TFormVideoDemo::Display(TImg *Frame)
{
	if (!LastFrame || LastFrame->bmiHeader.biWidth != Frame->GetWidth() || LastFrame->bmiHeader.biHeight != Frame->GetHeight())
	{
		if (LastFrame)
		{
			GlobalFree(LastFrame);
		}
		LastFrame = (LPBITMAPINFO)GlobalAlloc(GMEM_FIXED, sizeof(BITMAPINFOHEADER) + Frame->GetWidth() * Frame->GetHeight() * 4);
		memset(LastFrame, 0, sizeof(BITMAPINFOHEADER));
		LastFrame->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		LastFrame->bmiHeader.biWidth = Frame->GetWidth();
		LastFrame->bmiHeader.biHeight = Frame->GetHeight();
		LastFrame->bmiHeader.biPlanes = 1;
		LastFrame->bmiHeader.biBitCount = 32;
		LastFrame->bmiHeader.biCompression = BI_RGB;
		Caption = FCaption + " - " + IntToStr(Frame->GetWidth()) + "x" + IntToStr(Frame->GetHeight());
	}

	int Height = Frame->GetHeight();
	int LineWidth = Frame->GetLineWidth();
	int RealWidth = Frame->GetWidth() * 4;

	BYTE *Src = Frame->GetBitmap() + (Height - 1) * LineWidth;
	BYTE *Dst = ((BYTE*)LastFrame) + sizeof(BITMAPINFOHEADER);

	for (int i = 0; i < Height; i++)
	{
		memcpy(Dst, Src, RealWidth);
		Src -= LineWidth;
		Dst += RealWidth;
	}

	PaintBoxVideo->OnPaint(PaintBoxVideo);
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::PaintBoxVideoPaint(TObject *Sender)
{
	if (!LastFrame)
	{
		return;
	}

	LPBITMAPINFO bmp = LastFrame;
	int Width = PaintBoxVideo->Width;
	int Height = PaintBoxVideo->Height;
	int Left = 0;
	int Top = 0;
	HDC hdc = PaintBoxVideo->Canvas->Handle;
	SetStretchBltMode(hdc, COLORONCOLOR);

	double r2 = (double)bmp->bmiHeader.biWidth / (double)bmp->bmiHeader.biHeight;
	if (FOutputAspectRatio)
	{
		double w = (FOutputAspectRatio * (double)bmp->bmiHeader.biHeight) / (double)bmp->bmiHeader.biWidth;
		r2 = ((double)bmp->bmiHeader.biWidth / w) / (double)bmp->bmiHeader.biHeight;
	}
	/*
	if (!PanelRight->Visible)
	{
		PanelRight->Width = ClientWidth - PaintBoxVideo->Height * r2;
		PanelRight->Visible = true;
	}
	*/
	double r1 = (double)PaintBoxVideo->Width / (double)PaintBoxVideo->Height;
	if (r1 > r2)
	{
		Width = r2 * Height;
		Top = 0;
		Left = (PaintBoxVideo->Width - Width) / 2;
	}
	else if (r1 < r2)
	{
		Height = Width / r2;
		Left = 0;
		Top = (PaintBoxVideo->Height - Height) / 2;
	}

	if (hdd)
	{
		DrawDibDraw(hdd, hdc, Left, Top, Width, Height, (LPBITMAPINFOHEADER)bmp, (byte*)bmp + bmp->bmiHeader.biSize + bmp->bmiHeader.biClrUsed * sizeof(RGBQUAD), 0, 0, bmp->bmiHeader.biWidth, bmp->bmiHeader.biHeight, DDF_SAME_HDC);
	}
	else
	{
		StretchDIBits(hdc, 0, 0, Width, Height, 0, 0, bmp->bmiHeader.biWidth, bmp->bmiHeader.biHeight, (byte*)bmp + bmp->bmiHeader.biSize + bmp->bmiHeader.biClrUsed * sizeof(RGBQUAD), bmp, DIB_RGB_COLORS, SRCCOPY);
	}
}

//---------------------------------------------------------------------------
void TFormVideoDemo::SetFullScreen(bool Value)
{
	if (Value != FFullScreen)
	{
		if (Value)
		{
			LastWidth = Width;
			LastHeight = Height;
			LastLeft = Left;
			LastTop = Top;
			BorderStyle = bsNone;
			BorderIcons.Clear();
			WindowState = wsMaximized;
			FormStyle = fsStayOnTop;
		}
		else
		{
			BorderStyle = bsSizeable;
			TBorderIcons bi = BorderIcons;
			bi<<biSystemMenu;
			bi<<biMinimize;
			bi<<biMaximize;
			BorderIcons = bi;
			WindowState = wsNormal;
			Width = LastWidth;
			Height = LastHeight;
			Left = LastLeft;
			Top = LastTop;
			FormStyle = fsNormal;
		}
		FFullScreen = Value;
	}
//	PanelRight->Visible = false;
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
	if (Key == 27)
	{
		SetFullScreen(false);
	}
	else if (Key == 13 && Shift.Contains(ssAlt))
	{
		SetFullScreen(true);
	}
}

//---------------------------------------------------------------------------
void TFormVideoDemo::SetOutputAspectRatio(double Value)
{
	FOutputAspectRatio = Value;
	PanelLeft->OnResize(PanelLeft);
}

//---------------------------------------------------------------------------
void TFormVideoDemo::SetSlideCount(int SlideCount)
{
	FSlideCount = SlideCount;
	PanelLeft->OnResize(PanelLeft);
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::FormResize(TObject *Sender)
{
//	PanelRight->Visible = false;
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::PaintBoxVideoDblClick(TObject *Sender)
{
	SetFullScreen(!FFullScreen);
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::PaintBoxSlidesPaint(TObject *Sender)
{
	TCanvas *Canvas = ((TPaintBox*)Sender)->Canvas;
	Canvas->FillRect(Rect(0, 0, ((TPaintBox*)Sender)->Width, ((TPaintBox*)Sender)->Height));

	if (FSlideCount > 0)
	{
		while (Slides.size() > FSlideCount)
		{
			delete Slides.pop();
		}

		int SlideWidth = PaintBoxSlides->Width / FSlideCount;
		HDC hdc = Canvas->Handle;
		SetStretchBltMode(hdc, COLORONCOLOR);
		for (unsigned int i = 0; i < FSlideCount && i < Slides.size(); i++)
		{
			TImg *Img = Slides.get(i);
			BITMAPINFO Header;
			memset(&Header, 0, sizeof(Header));
			Header.bmiHeader.biSize = sizeof(Header.bmiHeader);
			Header.bmiHeader.biWidth = Img->GetWidth();
			Header.bmiHeader.biHeight = Img->GetHeight();
			Header.bmiHeader.biBitCount = 32;
			Header.bmiHeader.biPlanes = 1;
			Header.bmiHeader.biCompression = BI_RGB;
			StretchDIBits(hdc, SlideWidth * i, ((TPaintBox*)Sender)->Height, SlideWidth, -((TPaintBox*)Sender)->Height, 0, 0, Header.bmiHeader.biWidth, Header.bmiHeader.biHeight, Img->GetBitmap(), &Header, DIB_RGB_COLORS, SRCCOPY);
		}
	}
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::Timer1Timer(TObject *Sender)
{
	if (!SourceSlides)
	{
		return;
	}

	while (!SourceSlides->empty())
	{
		Slides.push(SourceSlides->pop());
		PaintBoxSlides->Invalidate();
	}
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::PanelLeftResize(TObject *Sender)
{
	if (FSlideCount > 0)
	{
		int SlideWidth = PaintBoxSlides->Width / FSlideCount;
		if (FOutputAspectRatio)
		{
			PaintBoxSlides->Height = SlideWidth / FSlideAspectRatio * (FOutputAspectRatio / FSlideAspectRatio);
		}
		else
		{
			PaintBoxSlides->Height = SlideWidth / FSlideAspectRatio;
		}
	}
	else
	{
		PaintBoxSlides->Height = 0;
	}
	PaintBoxSlides->Invalidate();
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::TimerImagesTimer(TObject *Sender)
{
	if (Images.size() > 0)
	{
		try
		{
			AnsiString Image = Images[ImageIndex];
			if (FLastImage != Image)
			{
				FLastImage = Image;
				Image1->Picture->LoadFromFile(Image);
			}
		}
		catch (...)
		{
		}
		ImageIndex = (ImageIndex + 1) % Images.size();
	}
}

//---------------------------------------------------------------------------
void __fastcall TFormVideoDemo::FormShow(TObject *Sender)
{
	TimerImages->OnTimer(TimerImages);
}

