#include "CCinematic.h"

#include "CPlayer.h"
CCinematic::CCinematic(void)
{
    init_blank();
}

CCinematic::CCinematic(char *filename)
{
    init(filename);

}

CCinematic::~CCinematic(void)
{
    unload();
}

void CCinematic::draw(BITMAP *backgr)
{
//    dialog.print(0,backgr,font,100,100,300,makecol(255,0,0));

    if(!(bgColour.r==255 && bgColour.g==0 && bgColour.b==255))
        clear_to_color(backgr,makecol(bgColour.r,bgColour.g,bgColour.b));
    
    for(int n=0 ; n<MAX_ACTORS ; n++)
    {
        if(actor[n].visible==true)
        {
            clear_to_color(actor[n].pic2,makecol(255,0,255));
            
            if(actor[n].flipped==true)
                draw_sprite_h_flip(actor[n].pic2,actor[n].pic,0,0);
            else
                draw_sprite(actor[n].pic2,actor[n].pic,0,0);
                
            if(actor[n].scale!=1)   //stretched
            {
                //new width and height
                int nw = (int)((float)actor[n].pic->w*actor[n].scale),
                    nh = (int)((float)actor[n].pic->h*actor[n].scale);

                stretch_sprite(backgr,actor[n].pic2,(int)actor[n].x,(int)actor[n].y,nw,nh);
            }
            else
                draw_sprite(backgr,actor[n].pic2,(int)actor[n].x,(int)actor[n].y);
        }
    }
    
    for(int n=0 ; n<MAX_TEXTBOXES ; n++)
    {
        //the textbox is visible
        if(textbox[n].visible==true)
        {
            if(textbox[n].bgc.r!=255 && textbox[n].bgc.g!=0 && textbox[n].bgc.b!=255 )
            rectfill(backgr,(int)textbox[n].x,(int)textbox[n].y,
                            (int)textbox[n].x+textbox[n].width,
                            (int)textbox[n].y+textbox[n].height,
                     makecol(textbox[n].bgc.r,textbox[n].bgc.g,textbox[n].bgc.b));
                   
            if(textbox[n].pic!=NULL)
                draw_sprite(backgr,textbox[n].pic,(int)textbox[n].x,(int)textbox[n].y);
           
            //it has to have a dialog
            if(textbox[n].dialogNum!=-1)
            { 
                dialog.print(textbox[n].dialogNum,backgr,textbox[n].font,
                        (int)textbox[n].x+textbox[n].textoffsetx,
                        (int)textbox[n].y+textbox[n].textoffsety,
                        textbox[n].width-textbox[n].textoffsetx,
                        makecol(textbox[n].textc.r,textbox[n].textc.g,textbox[n].textc.b));
                    
                if(bWaitForKey==true)    
                {
                    textprintf_ex(backgr,textbox[n].font,(int)(textbox[n].x+textbox[n].width-100),(int)(textbox[n].y+textbox[n].height-15),makecol(hitEnterColour,hitEnterColour,hitEnterColour),-1,"Hit Enter"); 
                }    
            }
        }
    }
}
    
int CCinematic::move(CPlayer *player, int s_x, int s_y)
{
    int finished=CIN_RUNNING;
    static bool bEnterPressed=false;
    
    if(iCurCommand < MAX_ACTIONS )
    {
        if(wait==0)
        {
            while(wait==0 && iCurCommand < MAX_ACTIONS  && bWaitForKey==false)
            {
                wait = executeCommand(command[iCurCommand],player,s_x,s_y);
                iCurCommand++;
            }
        }
        else if(wait>0)
        {
            wait--;
            for(int n=0 ; n<MAX_ACTORS ; n++)
            {
                if(actor[n].visible==true)
                {
                    actor[n].x+=actor[n].dx;
                    actor[n].y+=actor[n].dy;
                    
                    //actor[n].dscale=-.005;
                    actor[n].scale+=actor[n].dscale;
                    //actor[n].scale = actor[n].destscale;
                
                    //if the actor is close enough to its destx and desty
                    if( abval( (int)actor[n].x - actor[n].destx ) < 5 &&
                        abval( (int)actor[n].y - actor[n].desty ) < 5)
                    {
                        //set all of the actors movement back to zero
                        actor[n].dx=0;  actor[n].dy=0;
                        actor[n].x = actor[n].destx;
                        actor[n].y = actor[n].desty;
                    }
                    
                    //if the actor's scale is close enough to its dest scale
                    if(abval( actor[n].scale - actor[n].destscale ) < .05)
                        actor[n].dscale=0;
                    
                }
            }
            
            if(notextwait==0)
            {
                for(int n=0 ; n<MAX_TEXTBOXES ; n++)
                {
                    if(textbox[n].visible==true)
                    {
                        textbox[n].x+=textbox[n].dx;
                        textbox[n].y+=textbox[n].dy;
                    
                        if( abval( (int)textbox[n].x - textbox[n].destx ) < 3 &&
                        abval( (int)textbox[n].y - textbox[n].desty ) < 3)
                        {
                            textbox[n].dx=0;    textbox[n].dy=0;
                        }
                    }
                
                    //the textbox is visible, and it has a dialog assigned to it
                    if(textbox[n].visible==true && textbox[n].dialogNum!=-1)
                        dialog.move(textbox[n].dialogNum);
            
                }
            }
            if(notextwait>0)
                notextwait--;
        }
    }
    
    if(wait==-1)    //means cinematic is done
    {
        finished=CIN_FINISHED;
        wait=0;
        on=false;
    }
    else if(wait < -1)  //means to run the game for a period of time
    {
        finished = wait;
        wait=0;
    }
    
    if(bWaitForKey==true)
    {
        hitEnterColour-=5;
        if(hitEnterColour<=0)
            hitEnterColour=255;   
    }    
    
    
    if(key[KEY_ENTER] && bEnterPressed==false)
    {
        if(bWaitForKey==true)
            bWaitForKey=false;
        else if(disallow_skip_scene==false) //only allow this if disallow_skip_scene is not set
        {
            for(int n=0 ; n<MAX_TEXTBOXES ; n++)
                if(textbox[n].visible==true && textbox[n].dialogNum!=-1)
                    dialog.moveToEnd(textbox[n].dialogNum);
            wait=0;
        }
        
        bEnterPressed=true;
    }
    else if(!key[KEY_ENTER])
        bEnterPressed=false;
    
    if(key[KEY_ESC])
    {
        iCurCommand=MAX_ACTIONS;
        bWaitForKey=false;
        wait=-1;
        finished=CIN_FINISHED;
        on=false;
        while(key[KEY_ESC]) poll_keyboard();
    }    
    
    return finished;
}
    
//returns true if command orders a wait
int CCinematic::executeCommand(CinematicCommand &c, CPlayer *player, int s_x, int s_y)
{
    int wait=0;
    /************CINEMATIC SETTINGS**********/
    if( strcmp(c.action,"disallowskip")==0 )
        disallow_skip_scene=true;
    else if( strcmp(c.action,"allowskip")==0 )
        disallow_skip_scene=false;
    else if(strcmp(c.action,"moveduringcin")==0 )
        move_game_during_cin=true;
    else if(strcmp(c.action,"nomoveduringcin")==0 )
        move_game_during_cin=false;    
    
    /************CINEMATIC CONTROLS********/
    if( strcmp(c.action,"move")==0 )
    {
        //move actor p1 to position (p2,p3)
        actor[c.p1].x = (int)c.p2;
        actor[c.p1].y = (int)c.p3;
    } 
    else if( strcmp(c.action,"show")==0 )
    {
        if(actor[c.p1].pic)
            actor[c.p1].visible=true;
    }
    else if( strcmp(c.action,"hide")==0 )
        actor[c.p1].visible=false;
    else if( strcmp(c.action,"wait")==0 )
        wait = c.p1;
    else if( strcmp(c.action,"waitdlength")==0)
    {
        wait = dialog.retDialogLength(c.p1);
    }
    else if( strcmp(c.action,"notextwait")==0)
    {
        wait = c.p1;        //wait normally
        notextwait = c.p1;  //also do the notext wait
    }
    else if( strcmp(c.action,"flip")==0 )
    {
        if(actor[c.p1].flipped==false)
            actor[c.p1].flipped=true;
        else
            actor[c.p1].flipped=false;
    }
    else if( strcmp(c.action,"setbgc")==0)
    {
        bgColour.r = c.p1;
        bgColour.g = (int)c.p2;
        bgColour.b = (int)c.p3;
    }
    else if( strcmp(c.action,"moveto")==0)
    {
        actor[c.p1].dx = (float)((int)c.p2 - actor[c.p1].x) / c.p4;
        actor[c.p1].dy = (float)((int)c.p3 - actor[c.p1].y) / c.p4;
        actor[c.p1].destx = (int)c.p2;
        actor[c.p1].desty = (int)c.p3;
        //wait = c.p4;
    }
    else if( strcmp(c.action,"setpic")==0)
    {
        if((int)c.p2<iNumPics)
        {
            actor[c.p1].pic = (BITMAP*)data[(int)c.p2].dat;
            actor[c.p1].pic2 = create_bitmap(actor[c.p1].pic->w,actor[c.p1].pic->h);
        }
    }
    else if( strcmp(c.action,"getkey")==0)
    {
        bWaitForKey=true;
    }
    else if( strcmp(c.action,"endcin")==0)
        wait=-1;
    else if( strcmp(c.action,"rungame")==0)
        wait = -c.p1;
    else if( strcmp(c.action,"scaleto")==0)
    {
        actor[c.p1].destscale = c.p2;
        actor[c.p1].dscale = (actor[c.p1].destscale - actor[c.p1].scale) / c.p3;

    }
    
    
    /**********TEXTBOX STUFF*****************/
    else if( strcmp(c.action,"tb_setbgc")==0)
    {
        textbox[c.p1].bgc.r=(int)c.p2;
        textbox[c.p1].bgc.g=(int)c.p3;
        textbox[c.p1].bgc.b=(int)c.p4;
    }
    else if( strcmp(c.action,"tb_settextc")==0)
    {
        textbox[c.p1].textc.r=(int)c.p2;
        textbox[c.p1].textc.g=(int)c.p3;
        textbox[c.p1].textc.b=(int)c.p4;
    }
    else if( strcmp(c.action,"tb_move")==0)
    {
        textbox[c.p1].x=(int)c.p2;
        textbox[c.p1].y=(int)c.p3;
    }
    else if( strcmp(c.action,"tb_setwh")==0)
    {
        textbox[c.p1].width=(int)c.p2;
        textbox[c.p1].height=(int)c.p3;
    }
    else if( strcmp(c.action,"tb_show")==0)
    {
        if(textbox[c.p1].font)
            textbox[c.p1].visible=true;
    }
    else if( strcmp(c.action,"tb_hide")==0)
        textbox[c.p1].visible=false;
    else if( strcmp(c.action,"tb_setdialog")==0)
    {
        textbox[c.p1].dialogNum=(int)c.p2;
        dialog.resetDialog((int)c.p2);
        hitEnterColour=255;
    }
    else if( strcmp(c.action,"tb_setfont")==0)
        textbox[c.p1].font=(FONT*)fonts[(int)c.p2].dat;
    else if( strcmp(c.action,"tb_settextoffset")==0)
    {
        textbox[c.p1].textoffsetx = (int)c.p2;
        textbox[c.p1].textoffsety = (int)c.p3;
    }
    else if( strcmp(c.action,"tb_moveto")==0)
    {
        textbox[c.p1].dx = (float)((int)c.p2 - textbox[c.p1].x) / c.p4;
        textbox[c.p1].dy = (float)((int)c.p3 - textbox[c.p1].y) / c.p4;
        textbox[c.p1].destx = (int)c.p2;
        textbox[c.p1].desty = (int)c.p3;
    }
    else if( strcmp(c.action,"tb_setpic")==0)
    {
        if(c.p2>=0)
        {
            textbox[c.p1].pic = (BITMAP*)data[(int)c.p2].dat;
        }
        else
            textbox[c.p1].pic=NULL;
    }
    else if( strcmp(c.action,"playsound")==0)
    {
        if(c.p1>=0 && sounds)
            play_sample((SAMPLE*)sounds[c.p1].dat,100,155,1000,FALSE);
    }
    
    
    /**************IN GAME CONTROL*************************/
    else if( strcmp(c.action,"movecamerato")==0)   
    {
        if(player)
        {
            player->return_character()->set_new_screen_pos(
                s_x +(int)c.p1,
                s_y +(int)c.p2
                /*200,400*/
            );
            //player->return_character()->set_max_speed(200);
        }
    }
    else if( strcmp(c.action,"resetcamera")==0)
    {
        if(player)
        {
            player->return_character()->set_new_screen_pos(-1,-1);
            //player->return_character()->set_new_screen_pos(s_x,s_y);
        }
    }
    
    return wait;
}
    
void CCinematic::init(char *filename)
{
    char temp[70];
    
    if(loaded==false)
    {
        loaded=true;
        init_blank();
        
        FILE *fp = fopen(filename,"rt");
        if(fp)
        {
            fscanf(fp,"%s",sDatafile);
            fscanf(fp,"%s",sFontsDatafile);
            fscanf(fp,"%s",sSoundsDatafile);
            fscanf(fp,"%d",&iNumPics);
            fscanf(fp,"%s",sDialog);
        
            int n=0;
            while(!feof(fp))
            {
                //fscanf(fp,"%s",command[n].action);
                fscanf(fp,"%s",temp);
                if(strcmp(temp,"::")==0)    //start comment
                {
                    //go untill closing comment symbol is found
                    do
                    {
                        fscanf(fp,"%s",temp);
                    } while(!(strcmp(temp,"::")==0));
                        
                }
                
                //then read in the next command
                strcpy(command[n].action,temp);
                fscanf(fp,"%d %f %f %f",&command[n].p1, &command[n].p2, &command[n].p3, &command[n].p4);
                command[n].exist=true;
                n++;
            }
            
            fclose(fp);
        
            data=load_datafile(sDatafile);
            fonts = load_datafile(sFontsDatafile);
            sounds = load_datafile(sSoundsDatafile);
            dialog.load(sDialog);
        }
    }
}

void CCinematic::unload(void)
{
    if(loaded==true)
    {
        for(int n=0 ; n<MAX_ACTORS ; n++)
        {
            if(actor[n].pic2)
                destroy_bitmap(actor[n].pic2);
        }   
    
        if(data)
            unload_datafile(data);
        if(fonts)
            unload_datafile(fonts);
        init_blank();
        
        loaded=false;
    }
}

void CCinematic::init_blank(void)
{
    iNumPics=0;
    iNumCommands=0;
    
    for(int n=0 ; n<MAX_ACTIONS ; n++)
        command[n].exist=false;
    
    for(int n=0 ; n<MAX_ACTORS ; n++)
    {
        actor[n].pic2=NULL;
        actor[n].visible=false;
        actor[n].x=0; actor[n].y=0; actor[n].dx=0; actor[n].dy=0;
        actor[n].destx=0; actor[n].desty=0;
        actor[n].flipped=false;
        actor[n].scale=1; actor[n].dscale=0; actor[n].destscale=1;
        actor[n].alpha=255; actor[n].dalpha=0; actor[n].destalpha=1;
        
    }
    for(int n=0 ; n<MAX_TEXTBOXES ; n++)
    {
        textbox[n].pic=NULL;
        textbox[n].visible=false;
        textbox[n].x=0; textbox[n].y=0;
        textbox[n].dialogNum=-1;
        textbox[n].width=300;
        textbox[n].height=150;
        textbox[n].bgc.r=255;textbox[n].bgc.r=0;textbox[n].bgc.r=255;
        textbox[n].textc.r=0;textbox[n].textc.g=0;textbox[n].textc.b=0;
        textbox[n].textoffsetx=2;   textbox[n].textoffsety=2;
        
    }
    
    iCurCommand=0;
    wait=0; notextwait=0;
    bgColour.r=255; bgColour.g=0; bgColour.b=255;
    bWaitForKey=false;
    on=false;
    loaded=false;
    hitEnterColour=255;
    
    disallow_skip_scene=false;
    move_game_during_cin=false;
}

void CCinematic::end(void)
{
    on=false;
}
