/** Doku:
public int AddRoute(string transporter, string* l_stops)
  Beschreibung:
    Setzt die aktuelle Route eines Transporters.
    Die Route hier ist allerdings nur die Liste von Haltepunkten - nicht der
    Rest, der in den Routen in den Transporter abgelegt ist.
    Eine neue Route ersetzt immer die bisherige Route
    Wird von /std/transport gerufen, wenn P_NO_TRAVELING nicht gesetzt ist.
  Rueckgabewerte:
    - 1: Transporter und Haltepunkt Eingetragen.
    - 0: Transporter oder Haltepunkt kein string|string*.
    - -1: Es wurde versucht einen Transporter in /p/ oder /players/
          einzutragen 
          und der Eintragende ist kein EM.

public int RemoveTransporter(string|object transporter)
public int RemoveStop(string|object stop)
  Beschreibung:
    Entfernt einen kompletten Transporter oder einen Haltepunkt aus dem
    Daemon.
  Rueckgabewerte:
    - 1: Erfolg.
    - 0: Transporter|Haltepunkt existiert nicht.
    - -1: Keine Berechtigung.

public varargs int|object* HasTransporter(object stop, string transporter_id)
  Beschreibung:
    Gibt eine Liste der Transporter aus, den den Haltepunkt anlaufen, oder
    prueft auf einen bestimmten Transporter.
  Rueckgabewerte:
    - 0: Haltepunkt ist kein Objekt, dem Haltepunkt sind keine Transporter
         zugeordnet,
         die Transporter sind nicht geladen
         oder, bei angabe von <transporter>: <transporter> faehrt den Hafen
         nicht an.
    - object*: Liste mit einem oder mehreren Transportern.
  Bemerkung:
    Auch bei der Angabe von <transporter_id> koennen mehrere Objekte
    zurueckgegeben werden, es wird mittels id() gefiltert.

public mixed RouteExists(object transporter, string dest)
  Beschreibung:
    Prueft auf korrekte Parameter und leitet die Anfrage an
    /std/transport weiter.
  Rueckgabewerte:
    - 0: <transporter> ist kein Objekt oder <dest> ist kein String.
    - Das Ergebnis von transporter->HasRoute(dest);

public mapping QueryTransporters()
public mapping QueryAllStops() 
public mapping QueryTransporterByStop(string stop)
public mapping QueryStopsByTransporter(string transporter)
  Beschreibung:
    Gibt das jewilige gefilterte oder ungefilterte Mapping aus.
  Rueckgabewerte:
    Mapping mit dem Ergebnis.
*/

#pragma strong_types,save_types,rtt_checks
#pragma pedantic,range_check,warn_deprecated
#pragma warn_empty_casts,warn_missing_return,warn_function_inconsistent
#pragma no_clone,no_shadow

#include <transport.h>
#include <wizlevels.h>
#include <daemon.h>

#define TRANSPORTER 0
#define STOP 1

#define MEMORY "/secure/memory"

// Propertyname zum Speichern der Reloadversuchszaehler
#define RELOAD_TRIES "p_lib_reload_try_counter"

// Key: string Schiff.
// Value0: string* Haefen, die von <Schiff> angefahren werden.
mapping transporters = ([]);
// Key: string Hafen
// Value0: string* Schiffe, die <Hafen> anfahren.
mapping stops = ([]);

protected void create()
{
  // Vom MEMORY die Daten abholen.
  // Wenn keine da, war vermutlich Reboot, dann muessen wir warten, bis die
  // Transporter sich wieder melden. Aber die Mappings muessen ins Memory
  // geschrieben werden.
  mapping tmp = MEMORY->Load("stops");
  if (mappingp(tmp))
  {
    stops = tmp;
  }
  else
  {
    if (MEMORY->Save("stops",stops) != 1)
      raise_error("Could not save memory to /secure/memory.");
  }
  tmp = MEMORY->Load("transporters");
  if (mappingp(tmp))
  {
    transporters = tmp;
  }
  else
  {
    if (MEMORY->Save("transporters",transporters) != 1)
      raise_error("Could not save memory to /secure/memory.");
  }
  set_next_reset(86400);
}

protected void reload_transporters(object *ships)
{
  if (!sizeof(ships))
    return;
  else if (sizeof(ships) > 1)
    call_out(#'reload_transporters, 45, ships[1..]);

  object s = ships[0];
  if (s)
  {
    object *inv = all_inventory(s);
    if (sizeof(inv))
    {
      // Wenn Spieler drin sind, muss auf jeden Fall gewartet werden.
      // Bei sonstigem Krempel nur dann, wenn wir das noch nicht oft genug
      // erfolglos versucht haben.
      // Bemerkung: eigentlich muesste man hier pruefen, was davon per
      // AddItem() erzeugt wurde. Das ist mir gerade aber zu aufwendig.
      if (sizeof(filter(inv, #'query_once_interactive))
          || s->QueryProp(RELOAD_TRIES) < 3)
      {
        s->SetProp(RELOAD_TRIES, s->QueryProp(RELOAD_TRIES) + 1);
        // naechsten reset vorziehen
        set_next_reset(10800);
        return;
      }
      // ansonsten ist uns das Inventar jetzt egal und bald Schrott...
    }
    string sname = object_name(s);
    s->remove(1);
    load_object(sname);
    // Und hoffentlich starten Transporter selber. Wenn nicht, muss hier evtl.
    // noch nen Continue hin.
  }
}

public void reset()
{
  set_next_reset(86400);
  // Zeit des Programms vom Standardtransporter herausfinden. Wenn der nicht
  // geladen ist, muss nix gemacht werden.
  object std_transport = find_object("/std/transport");
  if (!std_transport)
    return;
  int std_time = program_time(std_transport);

  // ueber alle Transporter laufen. Wenn der Transport aelter ist als
  // /std/transport, wird er neu gelauden.
  // Das kann Nebenwirkungen haben. Aber in diesem Fall sollte man besser
  // den Transporter so bauen, dass es OK ist.
  // Aber speziell bei VC-Transportern ist fraglich, wie gut das
  // funktioniert...
  // Und es funktioniert nur fuer Blueprints.
  object *old_ships = map(transporters, function object (string sname)
      {
        object ship = find_object(sname);
        if (ship && !clonep(ship) && program_time(ship) < std_time)
          return ship;
        return 0;
      } );
  old_ships -= ({0});
  if (sizeof(old_ships))
    reload_transporters(old_ships);
}

varargs int remove(int s)
{
  destruct(this_object());
  return 1;
}

// Loeschfunktion
private int _remove_data(string|object key, int what)
{
  mapping first,second;
  // Erstmal die Arbeitsmappings befuellen.
  if(what==TRANSPORTER)
  {
    first=transporters;
    second=stops;
  }
  else
  {
    first=stops;
    second=transporters;
  }

  // Key auf einen String normalisieren.
  if(objectp(key))
  {
    key=object_name(key);
  }

  if(!member(first,key))
  {
    return 0;
  }

  // Erstmal aus dem jeweils anderen Mapping austragen.
  foreach(string s : first[key])
  {
    // Nicht existent oder nicht zugeordnet -> weiter.
    if(!member(second,s) || member(second[s],key)==-1)
    {
      continue;
    }
    second[s]-=({key});
    if (!sizeof(second[s]))
      m_delete(second,s);
  }
  // Jetzt noch aus dem eigenen Mapping austragen.
  m_delete(first,key);
  return 1;
}

// Ein komplettes Schiff entfernen.
public int RemoveTransporter(object|string transporter)
{
  if (extern_call()
      && previous_object() != transporter
      && !IS_ELDER(getuid(previous_object())))
      return -1;
  return _remove_data(transporter,TRANSPORTER);
}

// Entfernt einen kompletten Hafen aus dem Daemon
public int RemoveStop(object|string stop)
{
  if (extern_call()
      && previous_object() != stop
      && !IS_ELDER(getuid(previous_object())))
      return -1;
  return _remove_data(stop,STOP);
}

// Setzt die aktuelle Route eines Transporters.
// Die Route hier ist allerdings nur die Liste von Haltepunkten - nicht der
// Rest, der in den Routen in den Transporter abgelegt ist.
// Wird von /std/transport gerufen, wenn P_NO_TRAVELING nicht gesetzt ist.
public int AddRoute(string transporter, string* l_stops)
{
  if (!stringp(transporter) || !pointerp(l_stops) || !sizeof(l_stops))
    return 0;

  if ((transporter[0..2] == "/p/" || transporter[0..8] == "/players/")
      && !IS_ARCH(getuid(previous_object()))) 
  {
    return -1;
  }

  // Damit sind alle Abfragen auf find_object(transporter|stop) ueberfluessig,
  // im Zweifelsfall knallt es naemlich hier. ;-)
  transporter = object_name(load_object(transporter));

  // Wenn die route bereits existiert, austragen. Dies ist noetig, weil die
  // Haltepunkte ja auch bereinigt werden muessen.
  if (member(transporters, transporter))
    RemoveTransporter(transporter);

  // Transporter eintragen, die Route wird dabei immer ueberschrieben, wenn
  // der Transporter schon bekannt ist. Ziel: hier ist immer die aktuell
  // konfigurierte Route drin.
  m_add(transporters, transporter, l_stops);

  // Nach obigen Schema, nur diesmal Haltepunkte und zugehoerige Schiffe 
  // eintragen.
  foreach(string stop : l_stops)
  {
    if (!member(stops,stop))
    {
      m_add(stops, stop, ({transporter}));
    }
    else if (member(stops[stop],transporter) == -1)
    {
      stops[stop] += ({ transporter });
    }
  }
  return 1;

}

// Abfrage ob ein Schiff einen Hafen anfaehrt.
public varargs int|object* HasTransporter(object stop,
                                          string transporter_id)
{
  if (!objectp(stop)) return 0;

  <string|object>* trans=stops[object_name(stop)];
  if (!pointerp(trans)) return 0;

  // Eigentlich sollten sich Transporter ordentlich abmelden... Aber zur
  // Sicherheit die nicht gefundenen Objekte ausfiltern.
  trans = map(trans, #'find_object) - ({0});

  // Wenn ne bestimmte ID gesucht wird, nur diese Transporter liefern.
  if (stringp(transporter_id))
    trans = filter_objects(trans, "id", transporter_id);

  return sizeof(trans) ? trans : 0;
}

public mixed RouteExists(object transporter, string dest)
{
  if (!objectp(transporter) || !stringp(dest))
  {
    return 0;
  }
  return transporter->HasRoute(dest);
}

public mapping QueryTransporters()
{
  return deep_copy(transporters);
}

public mapping QueryAllStops()
{
  return deep_copy(stops);
}

// Liefert alle Transporter mit ihren Haltepunkten zurueck, die diesen Halt ansteuern.
public mapping QueryTransportByStop(string stop)
{
  mapping res=m_allocate(4);
  foreach(string s, string* arr : transporters)
  {
    if(member(arr,stop)!=-1)
    {
      m_add(res,s,arr);
    }
  }
  return res;
}

// Liefert alle Haltepunkte mit ihren Transportern zurueck, die dieser
// transporter ansteuert.
public mapping QueryStopsByTransporter(string transporter)
{
  mapping res=m_allocate(4);
  foreach(string s, string* arr : stops)
  {
    if(member(arr,transporter)!=-1)
    {
      m_add(res,s,arr);
    }
  }
  return res;
}

