/** 
 *  _   _        _  _                           _             
 * | |_| |  ___ | || |  ___   __ _  _ __  _ __ (_)  ___  _ __ 
 * |  _  | / _ \| || | / __| / _` || '__|| '__|| | / _ \| '__|
 * | | | ||  __/| || || (__ | (_| || |   | |   | ||  __/| |   
 * |_| |_| \___||_||_| \___| \__,_||_|   |_|   |_| \___||_|   
 * 
 *  (c) 2001 Free Lunch Design, Teknisk-IT, AerotechTelub
 *			  http://www.freelunchdesign.com
 * 
 * This source code is released as is under GPL (General Public
 * License). Please refer to license.txt for more information.
 * 
 */
 
#include <stdio.h>
#include "main.h"
#include "object.h"
#include "sector.h"

sector :: sector(int nx, int ny) {
	x = nx;
	y = ny;
	obj = NULL;	
}

sector :: ~sector() {}

// places 'o' first in list
void sector::add_object(object *o) {
	if (o == NULL) return;
	if (obj != NULL) obj->prev = o;
	o->prev = NULL;
	o->next = obj;
	o->sect = this;
	obj = o;
}

// removes a specific object from list
void sector::remove_object(object *o) {
	object *tmpo = obj;

	while (tmpo != o && tmpo != NULL) tmpo = tmpo->next;
	if (tmpo == NULL) return;

	// remove object from sector
	if (o->prev == NULL) {  // first obj
		obj = o->next;
		if (obj != NULL) obj->prev = NULL;
	}
	else if (o->next == NULL) {	// last obj
		o->prev->next = NULL;		
	}
	else {	// any other obj
		o->prev->next = o->next;
		o->next->prev = o->prev;
	}

	// clear up object
	o->next = NULL;
	o->prev = NULL;
	o->sect = NULL;
}

object *sector::get_objects() {
	return obj;
}






/////////////////////////////////////////////
//   sector_space
/////////////////////////////////////////////



sector_space::sector_space(int ox, int oy, int w, int h) {
	if (w * h > MAX_SECTORS) {
		my_alert("sector_space::sector_space", "Too big array, prepare for crash!");
		return;
	}

	width = w;
	height = h;
	origin_x = ox;
	origin_y = oy;

	for(int i=0;i<MAX_SECTORS;i++)
		s[i] = NULL;

	for(int y=0;y<height;y++)
		for(int x=0;x<width;x++) 
			s[x + width * y] = new sector(x, y);
}

sector_space::~sector_space() { 
	for(int i=0;i<MAX_SECTORS;i++)
		if (s[i] != NULL)
			s[i]->~sector();
}

 
sector *sector_space::get_sector(int sx, int sy) {
	int x = (sx - origin_x) / SECTOR_W;
	int y = (sy - origin_y) / SECTOR_H;
	if (x < 0 || x >= width || y < 0 || y >= height) return NULL;
	return s[x + width * y];
}

 
void sector_space::add_object(object *o) {
	int x,y;
	sector *new_sector = NULL;

	// calc new sector
	x = (o->x - origin_x) / SECTOR_W;
	y = (o->y - origin_y) / SECTOR_H;

	if (x < 0 || x >= width || y < 0 || y >= height) return;

	new_sector = s[x + width * y];

	// if same sector, exit
	if (new_sector == o->sect) return; 

	// remove from old sector, if any
	if (o->sect != NULL) o->sect->remove_object(o);

	// add to new sector
	new_sector->add_object(o);
}
