/*   Copyright 2005,2006 Paweł Niegowski
*
*    This file is part of Fenrir.
*
*    Fenrir is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    Fenrir is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with Fenrir; if not, write to the Free Software
*    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include "main.h"
#include "script.h"
#include "console.h"
#include "particle.h"
extern "C"
{
 #include <lua.h>
 #include <lauxlib.h>
 #include <lualib.h>
}

lua_State *vm;

int _LUA_alert(lua_State *l)
{
 if(lua_gettop(l) < 1) return 0;
 char message[300];
 strcpy(message,lua_tostring(l,1));
 allegro_message(message);
 return 0;
}


int _LUA_add_particle_system(lua_State *l)
// ParticleSystem *add_particle_system(max_particles,color,trail,trail_mod);
{
 if(lua_gettop(l) < 4) { console_add_line("ERROR: add_particle_system called with insufficient arguments"); }
 unsigned int max_particles,color,trail,trail_mod;
 max_particles = (unsigned int)lua_tonumber(l,1);
 color = (unsigned int)lua_tonumber(l,2);
 trail = (unsigned int)lua_tonumber(l,3);
 trail_mod = (unsigned int)lua_tonumber(l,4);
 ParticleSystem *ps = new ParticleSystem(max_particles,color,trail,trail_mod);
 lua_pushnumber(l,(int)ps);
 return 1;
}

int _LUA_set_box_emitter(lua_State *l)
// void set_box_emitter(ParticleSystem *ps,x,y,w,h,vx,vy,vx2,vy2,pps,lmin,lmax)
//   now that's a lot of arguments, isn't it?
{
 if(lua_gettop(l) < 12) { console_add_line("ERROR: set_box_emitter called with insufficient arguments"); }
 ParticleSystem *ps;
 int x,y,w,h,pps,lmin,lmax;
 float vx,vy,vx2,vy2;
 ps = ((ParticleSystem*)(int)lua_tonumber(l,1));
 x = (int)lua_tonumber(l,2);
 y = (int)lua_tonumber(l,3);
 w = (int)lua_tonumber(l,4);
 h = (int)lua_tonumber(l,5);
 vx = lua_tonumber(l,6);
 vy = lua_tonumber(l,7);
 vx2 = lua_tonumber(l,8);
 vy2 = lua_tonumber(l,9);
 pps = (int)lua_tonumber(l,10);
 lmin = (int)lua_tonumber(l,11);
 lmax = (int)lua_tonumber(l,12);
 ps->set_box_emitter(x,y,w,h,vx,vy,vx2,vy2,pps,lmin,lmax);
 return 0;
}

int _LUA_set_polar_mode(lua_State *l)
// void set_polar_mode(ParticleSystem *ps, polar_radius, polar_scaling)
{
 if(lua_gettop(l) < 3) { console_add_line("ERROR: set_polar_mode called with insufficient arguments"); }
 ParticleSystem *ps;
 ps = (ParticleSystem*)(int)lua_tonumber(l,1);
 ps->polar_mode = true;
 ps->polar_radius = lua_tonumber(l,2);
 ps->polar_scaling = lua_tonumber(l,3);
 return 0;
}

int _LUA_set_high_offset(lua_State *l)
// void set_high_offset(Object *o, offset)
{
 if(lua_gettop(l) < 2) { console_add_line("ERROR: set_high_offset called with insufficient arguments"); }
 Object *o = (Object*)(int)lua_tonumber(l,1);
 o->high_offset = (int)lua_tonumber(l,2);
 return 0;
}

int _LUA_get_coords(lua_State *l)
// int,int get_coords(Object *o)
{
 if(lua_gettop(l) < 1) { console_add_line("ERROR: get_coords called with no arguments"); }
 Object *o = (Object*)(int)lua_tonumber(l,1);
 lua_pushnumber(l,o->getx());
 lua_pushnumber(l,o->gety());
 return 2;
}

int _LUA_animator_remove(lua_State *l)
// void animator_remove(Object *o, int timer)
{
 if(lua_gettop(l) < 2) { console_add_line("ERROR: animator_remove called with insufficient arguments"); }
 Object *o = (Object*)(int)lua_tonumber(l,1);
 o->animators.push_back(new RemoveAnimator((int)lua_tonumber(l,2)));
 return 0;
}

int _LUA_animator_attach(lua_State *l)
// void animator_attach(Object *o, Object *dest)
{
 if(lua_gettop(l) < 2) { console_add_line("ERROR: animator_attach called with insufficient arguments"); }
 Object *o = (Object*)(int)lua_tonumber(l,1);
 o->animators.push_back(new AttachAnimator((Object*)(int)lua_tonumber(l,2)));
 return 0;
}

int _LUA_effect_colorize(lua_State *l)
// void effect_colorize(Object *o, color, duration)
{
 if(lua_gettop(l) < 3) { console_add_line("ERROR: effect_colorize called with insufficient arguments"); }
 Object *o = (Object*)(int)lua_tonumber(l,1);
 o->effect_colorize((int)lua_tonumber(l,2),(int)lua_tonumber(l,3));
 return 0;
}

void script_init()
{
 vm = lua_open();
 if(!vm) { allegro_message("ERROR: couldn't initialize Lua virtual machine.\n"); return; }
 luaopen_base(vm);
 luaopen_table(vm);
 lua_register(vm,"alert",_LUA_alert);
 lua_register(vm,"add_particle_system",_LUA_add_particle_system);
 lua_register(vm,"set_box_emitter",_LUA_set_box_emitter);
 lua_register(vm,"set_polar_mode",_LUA_set_polar_mode);
 lua_register(vm,"set_high_offset",_LUA_set_high_offset);
 lua_register(vm,"get_coords",_LUA_get_coords);
 lua_register(vm,"animator_remove",_LUA_animator_remove);
 lua_register(vm,"animator_attach",_LUA_animator_attach);
 lua_register(vm,"effect_colorize",_LUA_effect_colorize);
}

void script_cleanup()
{
 lua_close(vm);
}

void script_setptr(char *name, void *ptr)
{
 lua_pushnumber(vm,(int)ptr);
 lua_setglobal(vm,name);
}

void script_run(char *script)
{
// if(luaL_loadstring(vm,script) || lua_pcall(vm,0,0,0))
 if(lua_dostring(vm,script))
 {
  console_add_line((char*)lua_tostring(vm,-1));
  lua_pop(vm,1);
 }
}
