// Aseprite
// Copyright (C) 2018-2023  Igara Studio S.A.
// Copyright (C) 2018  David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "app/cmd/set_slice_key.h"
#include "app/cmd/set_slice_name.h"
#include "app/script/docobj.h"
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include "app/script/userdata.h"
#include "app/tx.h"
#include "doc/slice.h"
#include "doc/sprite.h"

namespace app {
namespace script {

using namespace doc;

namespace {

int Slice_eq(lua_State* L)
{
  const auto a = may_get_docobj<Slice>(L, 1);
  const auto b = may_get_docobj<Slice>(L, 2);
  lua_pushboolean(L, (!a && !b) || (a && b && a->id() == b->id()));
  return 1;
}

int Slice_get_sprite(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  push_docobj(L, slice->owner()->sprite());
  return 1;
}

int Slice_get_name(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  lua_pushstring(L, slice->name().c_str());
  return 1;
}

int Slice_get_bounds(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  if (!slice->empty())
    push_new<gfx::Rect>(L, slice->begin()->value()->bounds());
  else
    lua_pushnil(L);
  return 1;
}

int Slice_get_center(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  if (!slice->empty() && slice->begin()->value()->hasCenter())
    push_new<gfx::Rect>(L, slice->begin()->value()->center());
  else
    lua_pushnil(L);
  return 1;
}

int Slice_get_pivot(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  if (!slice->empty() && slice->begin()->value()->hasPivot())
    push_new<gfx::Point>(L, slice->begin()->value()->pivot());
  else
    lua_pushnil(L);
  return 1;
}

int Slice_set_name(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  const char* name = lua_tostring(L, 2);
  if (name) {
    Tx tx(slice->sprite());
    tx(new cmd::SetSliceName(slice, name));
    tx.commit();
  }
  return 0;
}

int Slice_set_bounds(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  gfx::Rect bounds = convert_args_into_rect(L, 2);
  SliceKey key;
  if (const SliceKey* srcKey = slice->getByFrame(0))
    key = *srcKey;
  key.setBounds(bounds);
  Tx tx(slice->sprite());
  tx(new cmd::SetSliceKey(slice, 0, key));
  tx.commit();
  return 0;
}

int Slice_set_center(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  gfx::Rect center = convert_args_into_rect(L, 2);
  SliceKey key;
  if (const SliceKey* srcKey = slice->getByFrame(0))
    key = *srcKey;
  key.setCenter(center);
  Tx tx(slice->sprite());
  tx(new cmd::SetSliceKey(slice, 0, key));
  tx.commit();
  return 0;
}

int Slice_set_pivot(lua_State* L)
{
  auto slice = get_docobj<Slice>(L, 1);
  gfx::Point pivot = convert_args_into_point(L, 2);
  SliceKey key;
  if (const SliceKey* srcKey = slice->getByFrame(0))
    key = *srcKey;
  key.setPivot(pivot);
  Tx tx(slice->sprite());
  tx(new cmd::SetSliceKey(slice, 0, key));
  tx.commit();
  return 0;
}

const luaL_Reg Slice_methods[] = {
  { "__eq", Slice_eq },
  { nullptr, nullptr }
};

const Property Slice_properties[] = {
  { "sprite", Slice_get_sprite, nullptr },
  { "name", Slice_get_name, Slice_set_name },
  { "bounds", Slice_get_bounds, Slice_set_bounds },
  { "center", Slice_get_center, Slice_set_center },
  { "pivot", Slice_get_pivot, Slice_set_pivot },
  { "color", UserData_get_color<Slice>, UserData_set_color<Slice> },
  { "data", UserData_get_text<Slice>, UserData_set_text<Slice> },
  { "properties", UserData_get_properties<Slice>, UserData_set_properties<Slice> },
  { nullptr, nullptr, nullptr }
};

} // anonymous namespace

DEF_MTNAME(Slice);

void register_slice_class(lua_State* L)
{
  using doc::Slice;
  REG_CLASS(L, Slice);
  REG_CLASS_PROPERTIES(L, Slice);
}

} // namespace script
} // namespace app
