
// ##################################################
// ##                index hvezd                   ##
// ##                                              ##
// ##################################################

#pragma once
#ifndef SPACE_INDEX_H
#define SPACE_INDEX_H

#include "common.h"

#include <set>
#include <map>
#include <vector>
#include <list>

#include "independent_constants.h"
#include "mathfunc.h"
#include "kdtree.h"

// ################################

struct spaceIndexItem
{
    dtIdentifier spaceSystemIndex_;
    vector_dbl_t position_;

    vector_dbl_t& getPosition(void) { return position_; }

    spaceIndexItem(const dtIdentifier ssi, const vector_dist_t& pos);
};

// ################################

class context;
class spaceIndex
{
private:
    std :: vector<spaceIndexItem*> items_;
    std :: map<dtIdentifier, spaceIndexItem*> spaces_;
    std :: multimap<dtIdentifier, dtIdentifier> ships; // dvojice hvezda-lod
    k2tree<spaceIndexItem, double> index_;
public:
    spaceIndexItem* getItem(dtIdentifier id);
    spaceIndexItem* getNearestItem(const vector_dist_t& position);
    void clean(void);
    void build(context* myctx);
    void addStar(spaceIndexItem* star);
    void moveShip(dtIdentifier ship, dtIdentifier from, dtIdentifier to);
    void addShip(dtIdentifier ship, dtIdentifier to);
    void removeShip(dtIdentifier ship, dtIdentifier from);
    std :: multimap<dtIdentifier, dtIdentifier>& getShips(void) { return ships; }
    void getShipsInArea(dtIdentifier area, std :: list<dtIdentifier>& ships);
    void starsByRegion(const dist_t xmin, const dist_t xmax, 
        const dist_t ymin, const dist_t ymax, std :: list<dtIdentifier>& result);
    ~spaceIndex();

    std :: vector<spaceIndexItem*> :: const_iterator starsBegin(void)   { return items_.begin();    }
    std :: vector<spaceIndexItem*> :: const_iterator starsEnd(void)     { return items_.end();      }
};

// ################################

#endif