#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/timer.h>
#include <graphics/modeid.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <intuition/screens.h>

#include "Shared/EE_precalc.h"
#include "Shared/EE_view.h"
#include "Shared/EE_timer.h"

#include "Renderer/EM_Structures.h"
#include "Renderer/EM_Render.h"
#include "Renderer/EM_Reader.h"
#include "Renderer/EM_Animation.h"
#include "Renderer/EM_Sequence.h"

#include "tunel/TN_Render.h"
#include "tunel/TN_Sequence.h"

#include "Incbiny.h"
#include "Music/Music_Play.h"

#include "sequences.h"

void ScaleBM(UBYTE *bm,UBYTE *dest,int w,int h,int nw,int nh);
void CleanUp(void);
void PrepareChunky(VOID);
void GetChunky(void);

#define ANGLES_NUMBER 180

extern TIMER *Timer;

LONG Mouse=0;

WORD Tab[8]={128,64,32,16,8,4,2,1};

UBYTE TextureMem[256*256];
ULONG BlackPal[256*3+4];
UBYTE Image[320*200];
UBYTE EndText[320*48];
DVIEW *DView;
ULONG WhitePal[772];

void main(void)
{
int i;

/*     if(AvailMem(MEMF_FAST)==0)
     {
     printf("    Hej! We're living almost in XXI Century!\n");
     printf("And you haven't got any fast mem? What's a lame!\n");
     exit(103);
     }
*/
	if(!InitTimer())
          {
          CleanUp();
          exit(103);
          }

   	if(!OpenBackView())
          {
          CleanUp();
          exit(103);
          }

      for(i=0;i<256*3;i++) BlackPal[1+i]=0x00000000;
      BlackPal[0]=0x01000000;
      for(i=0;i<256*3;i++) WhitePal[1+i]=0xffffffff;
      WhitePal[0]=0x01000000;

     if(!PrecalcRotateTable(180, 1024))
          {
          CleanUp();
          exit(103);
          }

     if(!PrecalcPerspectiveTable(300, 1124))
          {
          CleanUp();          
          exit(103);
          }

     if(!PrecalcArcSineTable())
          {
          CleanUp();
          exit(103);
          }

     ScaleBM(Light,TextureMem,128,128,256,256);

	if((DView = OpenView(320, 200, 8, PAL_MONITOR_ID|LORES_KEY, (ULONG *)Pal,DVF_CHUNKY|DVF_INTERLEAVED|DVF_DBUFF|DVF_CENTER))==NULL)
          {
             printf("Please run setpatch!\n");
               CleanUp();
               exit(0);

          }

     StartMusic(Module);


     OOPS_AnimList[19].Parameter=(LONG)Pal;

     EM_Sequence(Vaapx,VAAPX_AnimList,TextureMem,Image,0);
     EM_Sequence(NoeBJ,NOEBJ_AnimList,TextureMem,Image,0);
     EM_Sequence(MadTim,VAAPX_AnimList,TextureMem,Image,0);
     EM_Sequence(OOps,OOPS_AnimList,TextureMem,Image,0);

     ScaleBM(BackGround,Image,128,128,320,200);

     FLOWER_AnimList[1].Parameter=(LONG)Pal;
     EM_Sequence(Flower,FLOWER_AnimList,TextureMem,Image,0);


     EM_Sequence(Nutka,NUTKI_AnimList,TextureMem,Image,6);


     ScaleBM(BackGround,TextureMem,128,128,256,256);
     TN_Sequence(Tunel,TUNEL_AnimList,TextureMem);

     ScaleBM(Light,TextureMem,128,128,256,256);
     EM_Sequence(Circles,CIRCLES_AnimList,TextureMem,Image,0);

     EM_Sequence(OOps,OOPS2_AnimList,TextureMem,Image,0);

     for(i=0;i<6;i++)
     {
     NUTKI_AnimList[4+(i*9)].Parameter=rand()%90;
     NUTKI_AnimList[5+(i*9)].Parameter=rand()%90;
     NUTKI_AnimList[6+(i*9)].Parameter=rand()%90;
     }

     EM_Sequence(Torus,NUTKI_AnimList,TextureMem,Image,6);

     EM_Sequence(Kolce,KOLCE_AnimList,TextureMem,Image,0);

     FLOWER_AnimList[1].Command=AC_OBJECT;
     FLOWER_AnimList[1].Parameter=0;
     FLOWER_AnimList[4].Parameter=140;
     EM_Sequence(Torus,FLOWER_AnimList,TextureMem,Image,0);

     EM_Sequence(OOps,OOPS1_AnimList,TextureMem,Image,0);

     GetChunky();
     PrepareChunky();
     InsertText(EndText,DView->Chunky);

//End text
	SafeRender(DView);
	DView->C2P(DView);
     FrameEvent();
	SwitchView(DView);

//ooo - to koniec?
     while(WaitMouse());

     FadeOutPalette(DView,(ULONG *)Pal,0,0,0,2*SEC);

     StopMusic();
     CleanUp();
}

void CleanUp(void)
{
	if(DView) CloseView(DView);
     CloseBackView();
     FreeRotateTable();
     FreePerspectiveTable();
     FreeArcSineTable();
     RemoveTimer();
}

void ScaleBM(UBYTE *bm,UBYTE *dest,int w,int h,int nw,int nh)
{
 UBYTE *bmc=bm;
 int i,j;

 ULONG fpxinc,fpxcur,fpyinc,fpycur;

 fpxinc=(ULONG)((ULONG)w*65535L)/(LONG)nw;

 fpyinc=(ULONG)((ULONG)h*65535L)/(LONG)nh;

 fpycur=0;

 for(j=0;j<nh;j++) {

	fpxcur=0;

	for(i=0;i<nw;i++) {
		dest[i]=bmc[fpxcur>>16];
		fpxcur+=fpxinc; }
	dest+=nw;
	bmc=&bm[(fpycur>>16) * w];
	fpycur+=fpyinc; }
}

void PrepareChunky(VOID)
{
int i,j,k;
UBYTE a;
LONG b=0;
  for(i=0;i<48;i++)
       for(j=0;j<40;j++)
          for(k=0;k<8;k++)
          {
               a=End[(i*40)+j];
               a=a&Tab[k];
               if(a) {EndText[b]=255;b++;}
               else  {EndText[b]=0;b++;}
          }
}

void GetChunky(void)
{
int i,j,k=0;

     for(i=0;i<200;i++)
       for(j=0;j<320;j++)
          {
          DView->Chunky[(i*320)+j]=ReadPixel(DView->DisplayRP,j,i);
          }
}
