#include "object.h"
#include "mymath.h"
#include "globals.h"
#include "camera.h"



std::deque<Object *> GameObjects;

Object *ObjectZOrder_list=NULL;


void DeleteFromGameObjects(Object *o) {
  std::deque<Object *>::iterator it;
  for (it = GameObjects.begin(); it!=GameObjects.end(); it+=1) {
    if ((*it) == o) {
      GameObjects.erase(it);
      delete o;
      break;
    }
  }
}


void UpdateObjectZSorting() {
  std::deque<Object *>::iterator it;
  ObjectZOrder_list = NULL;
  for (it = GameObjects.begin(); it!=GameObjects.end(); it+=1) {
    AddObjectZOrder((*it));
  }
}



void AddObjectZOrder(Object *v) {
   int b, l;
   Object *iter, *l_iter;
   b = 0;
   l = 0;
   v->set_z_prev(NULL);
   v->set_z_next(NULL);
   if (ObjectZOrder_list == NULL) {
      ObjectZOrder_list = v;
   }
   else {
     iter = ObjectZOrder_list;
      while (l == 0) {
        if (v->GetZ() < iter->GetZ()) {
          if (iter == ObjectZOrder_list) {
            iter->set_z_prev(v);
            v->set_z_next(iter);
            ObjectZOrder_list = v;
          }
          else {
            iter->get_z_prev()->set_z_next(v);
            v->set_z_prev(iter->get_z_prev());
            v->set_z_next(iter);
            iter->set_z_prev(v);
          }
          b = 1;
          break;
        }
        l_iter = iter;
        iter = iter->get_z_next();
        if (iter == NULL) {l = 1; iter = l_iter;}
      }
      if (ObjectZOrder_list->get_z_next()==NULL) iter = ObjectZOrder_list;
      if (!b) {
        v->set_z_prev(iter);
        iter->set_z_next(v);
      }
   }
}


void DrawObjectsZOrder() {
  Object *it;
  it = ObjectZOrder_list;
  while (it != NULL) {
    it->Draw();
    it = it->get_z_next();
  }
}



void Object::Update() {
  rx = RSX(x-Camera_X); ry = RSY(y-Camera_Y); rw = RSW(w); rh = RSH(h);
  if (!Pause) sprite.Update();
  actual = sprite.GetActualBitmap();
  UpdateGeneral();
}



bool Object::InsideScreen() {
  if ((rx-rw/2 > -rw) && (rx+rw/2 < SCREEN_W+rw) && (ry-rh/2 > -rh) && (ry+rh/2 < SCREEN_H+rh)) {
    return true;
  }
  else return false;
}


void Object::Draw() {
  DrawGeneral();
  if (actual != NULL) {
    if (InsideScreen()) {
      DRAW_TRANSFORMED(actual->get_bit(), rx, ry, rw, rh, angle, 0);
    }
  }
}
