#include <stdio.h>
#include <string.h>
#include "CRevengeScript.h"

#include "CMapObject.h"
#include "CCharacter.h"
void CRevengeScript::init(void)
{
    for(int n=0 ; n<MAX_COMMANDS; n++)
    {
        command[n].exist=false;
    
    }
    number_of_commands=0;
}

bool CRevengeScript::load_script(char *filename)
{
    FILE *fp;
    
    if(fp=fopen(filename,"r"))
    {
        fscanf(fp,"%d",&number_of_commands);
        
        for(int n=0 ; n<number_of_commands, n<MAX_COMMANDS; n++)
        {
            fscanf(fp,"%s",command[n].condition);
            fscanf(fp,"%s",command[n].acting_on);
            fscanf(fp,"%s",command[n].action);
            fscanf(fp,"%d %d %d",&command[n].p1,&command[n].p2,&command[n].p3);
            command[n].exist=true;
        
        }  
    }
    else
        return false;
        
    paused=false;    
    
    return true;
}

void CRevengeScript::display_script(BITMAP *backgr)
{
    for(int n=0 ; n<number_of_commands ; n++)
    {
        textprintf_ex(backgr,font,100,100+n*20,makecol(200,155,0),-1,"%s %s %s %d %d %d",
        command[n].condition,command[n].acting_on,command[n].action,command[n].p1,command[n].p2,command[n].p3);
    
    }
}

void CRevengeScript::check_condition(CMapObject *object, CMapObject *player, CParts *parts, CDialog *dialog, CCinematic *ingameCin)
{ 

    for(int n=0 ; n<number_of_commands ; n++)
    {
        if(object && player)
        {
        if(command[n].exist)
        {
            //check this command and see if ketchup is within a given distance of that object
            if(strcmp(command[n].condition,"withinp1")==0 && get_dist(object->ret_centx(),object->ret_centy(),player->ret_centx(),player->ret_centy())<=command[n].p1) 
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);  
            }   
            
            //checks to see if the ketchup bottle is vertically between the two mocement points of the object
            //and horizontally within p1 pixels of it
            else if(strcmp(command[n].condition,"vertwithinmp1andmp2")==0 && fabs(player->ret_centx()-object->ret_centx())<command[n].p1 && player->y>object->p1.y && player->y<object->p2.y)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }   
            else if(strcmp(command[n].condition,"offscreenmoving")==0 && (fabs(player->ret_centx()-object->ret_centx())>700 || fabs(player->ret_centy()-object->ret_centy())>520) && object->still==false)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }   
            else if(strcmp(command[n].condition,"moving")==0 && object->still==false)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"hitground")==0 && object->touching_ground==true)
            {               
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }   
            else if(strcmp(command[n].condition,"atp1frame")==0 && object->anim.ret_frame_number()==command[n].p1)
            {                
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }    
            else if(strcmp(command[n].condition,"atp3frame")==0 && object->anim.ret_frame_number()==command[n].p3)
            {                
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }   
            else if(strcmp(command[n].condition,"nottouchingplayer")==0 && check_col_with_bitmap(object->iWidth,object->iHeight,player->iWidth,player->iHeight,object->x,object->y,player->x,player->y)==false)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
                //while(!key[KEY_ENTER]){}
            }
            else if(strcmp(command[n].condition,"touchingplayer")==0 && check_col_with_bitmap(object->iWidth,object->iHeight,player->iWidth,player->iHeight,object->x,object->y,player->x,player->y)==true)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"touchingplayeronground")==0 && check_col_with_bitmap(object->iWidth,object->iHeight,player->iWidth,player->iHeight,object->x,object->y,player->x,player->y)==true
                    && /*((CCharacter*)player)->jumped==-1*/player->touching_ground==true)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"isflamed")==0 && object->flamed==true)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"notflamed")==0 && object->flamed==false)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"stopped")==0 && object->not_moving==true && ((CCharacter*)object)->retDucked()==false)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"isjumped")==0 && ((CCharacter*)object)->jumped>13)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"inair")==0 && ((CCharacter*)object)->touching_ground==false && ((CCharacter*)object)->jumped > 0 && ((CCharacter*)object)->jumped < 13 )
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"isjumping")==0 && ((CCharacter*)object)->start_jump>0)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"turningaround")==0 && ((CCharacter*)object)->key_value!=object->dir && ((CCharacter*)object)->touching_ground==true && object->not_moving==false && abval(object->dx)>.75)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"iswalking")==0 && object->not_moving==false && /*((CCharacter*)object)->dy==0*/((CCharacter*)object)->touching_ground==true && ((CCharacter*)object)->retDucked()==false)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"isducking")==0 && ((CCharacter*)object)->retDucked()==true)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }
            else if(strcmp(command[n].condition,"isdying")==0 && ((CCharacter*)object)->ret_dying()==true)
            {
                check_acting_on(n,object,player,parts,dialog,ingameCin);
            }    

            }
        }
    }
}

extern bool quit_level_menu_on;

void CRevengeScript::check_acting_on(int n, CMapObject *object, CMapObject *player, CParts *parts, CDialog *dialog, CCinematic *ingameCin)
{
    if(strcmp(command[n].action,"unpause")==0)
    {
        paused=false;
    }
    
    if(paused==false)
    {
    
        if(strcmp(command[n].acting_on,"anim")==0)    //if it is acting on an animation
        {
            do_anim_actions(n,object);
        }
        else if(strcmp(command[n].acting_on,"script")==0)
        {
            if(strcmp(command[n].action,"killscript")==0)
            {
                for(int i=0 ; i<number_of_commands ; i++)
                    command[i].exist=false;
            }
        }
        else if(strcmp(command[n].acting_on,"cin")==0)
        {
            //while(!key[KEY_ENTER]){}
        
            if(ingameCin)
            {
                ingameCin->unload();
                ingameCin->init(command[n].action);
                ingameCin->start();
                //command[n].exist=false;
            }
        }
        else if(strcmp(command[n].acting_on,"player")==0)
        {
            if(strcmp(command[n].action,"addp1tody")==0)
            {
                player->dy+=command[n].p1;
                ((CCharacter*)player)->not_key_down();  //stop it from ducking
                ((CCharacter*)player)->start_jump=0;
            }
        }
        else if(strcmp(command[n].acting_on,"enim")==0) //acting on the behaviour of an enemy
        {
            if(strcmp(command[n].action,"move")==0)
            {
                if(object->still==true)
                {             
                    object->still=false;
                    if(player->ret_centx() < object->ret_centx())
                    {
                        object->dir=LEFT;
                        object->dx=-0.001;
                    }    
                    else
                    {
                        object->dir=RIGHT;
                        object->dx=0.001;
                    }    
                }
            }
            else if(strcmp(command[n].action,"setyaccel")==0)
            {
                if(object->still==true)
                    ((CCharacter*)object)->y_accel=command[n].p2;   
            }    
        }
        else if(strcmp(command[n].acting_on,"parts")==0)
        {
            if(strcmp(command[n].action,"spraybrown")==0)
            {
                //void create_colour_burst(float x, float y, int density, float speed, char *_colour, int p_radius);
                parts->create_colour_burst(object->ret_centx(),object->ret_centy(),20,4,"brown",2);       
            }  
            else if(strcmp(command[n].action,"spraysmall")==0)
            {
                int c = makecol(command[n].p1,command[n].p2,command[n].p3);
                parts->create_colour_burst(object->ret_centx(),object->ret_centy(),75,4,c,1);
                //parts->create_colour_burst(object->ret_centx(),object->ret_centy(),20,4,c,2); 
                //parts->create_colour_burst(object->ret_centx(),object->ret_centy(),20,4,"brown",2);  
            } 
            else if(strcmp(command[n].action,"spraysparks")==0)
            {
     
                int c = makecol(255,(int)(205+rand()%40),60);
                parts->create_colour_burst(object->retX()+command[n].p2,object->retY()+command[n].p3,1,4,c,1);   
            }    
        }
        else if(strcmp(command[n].acting_on,"sound")==0)
        {
            if(strcmp(command[n].action,"playsound")==0)
            {
                static int voice=-1;
                
                if(voice==-1 || voice_get_position(voice)==-1)
                {
                 
                    voice = allocate_voice((SAMPLE*)object->data[sound00+command[n].p1].dat);
                
                    voice_set_volume(voice,250);
                    voice_start(voice);
                }
                if(voice_get_position(voice)==-1)
                    release_voice(voice);
                //play_sample((SAMPLE*)object->data[sound00+command[n].p3].dat,200,125,1000,FALSE);
                
    
    //            if(object->consumed_wav)
    //                play_sample(object->consumed_wav,100,125,1000,FALSE);
            }
        }
        else if(strcmp(command[n].acting_on,"game")==0)
        {
            if(strcmp(command[n].action,"exitlevel")==0)
                quit_level_menu_on=true;
        }
        else if(strcmp(command[n].action,"displaydialog")==0)
        {
            
        }
    }
    
    if(strcmp(command[n].action,"destroyparent")==0)
    {
        //object->exist=false;
        object->consumed=true;
        //object->still=true;
    }
    if(strcmp(command[n].action,"pause")==0)
    {
        paused=true;
    }
}

void CRevengeScript::do_anim_actions(int n, CMapObject *object)
{
    if(strcmp(command[n].action,"stop")==0)
    {
        object->stop_anim();
        object->anim.set_frame(0);
        if(command[n].p1==1)    //means wait until animation is finished
            object->anim.set_new_bounds(0,0);
    }
    else if(strcmp(command[n].action,"playbetweenp1p2")==0  && object->anim.readyforanim)
    {
        if(command[n].p3<0)    //dont wait for current frames to finish
        {
            object->anim.set_frame_wait(-command[n].p3);
            object->anim.set_bounds(command[n].p1,command[n].p2);
        
            //only play the animation if the current frame is not already within the play bounds of the animation
            //if(!(command[n].p1 < object->anim.ret_frame_number() && command[n].p2 >= object->anim.ret_frame_number()))
            if(object->anim.ret_frame_number()<=command[n].p1 || object->anim.ret_frame_number()>command[n].p2)
            {
                object->anim.start_anim(command[n].p1);
                //object->anim.reset_countdown();
            }
        }
        else if(command[n].p3>0)   //wait for current anim to finish
        {
            object->anim.set_frame_wait(command[n].p3);
            object->anim.set_new_bounds(command[n].p1,command[n].p2);
        }
    }
    else if(strcmp(command[n].action,"notreadyforanim")==0)
    {
        object->anim.readyforanim=false;
    }
    else if(strcmp(command[n].action,"isreadyforanim")==0)
    {
        object->anim.readyforanim=true;
    }
    else if(strcmp(command[n].action,"gotoframep3")==0 && object->anim.ret_frame_number()==0)
    {
        object->anim.set_bounds(command[n].p3,command[n].p3);
        object->anim.start_anim(command[n].p3);
    }
    else if(strcmp(command[n].action,"resetanim")==0)
        object->anim.reset_anim();
        
}

