// MorgenGrauen MUDlib
//
// room/exits.c -- room exits handling 
//
// $Id: exits.c 9497 2016-02-21 14:20:03Z Zesstra $

/*
 * Exits of the room (obvious ones, doors, and special ones)
 * we define the following function for easy reference:
 * GetExits() - return a string containing an "Obvious Exits" Statement
 *
 * The exits are implemented as properties P_EXITS
 * They are stored locally (_set_xx, _query_xx)
 * as mapping to speed up the routines in this module.
 *
 */

#pragma strong_types
#pragma save_types
#pragma pedantic
#pragma range_check
#pragma no_clone

#define NEED_PROTOTYPES
#include <thing/properties.h>
#include <moving.h>
#include <room/exits.h>
#include <hook.h>
#include <exploration.h>
#undef NEED_PROTOTYPES

#include <sys_debug.h>
#include <config.h>
#include <properties.h>
#include <defines.h>
#include <daemon.h>
#include <doorroom.h>
#include <routingd.h>

#define NUMBERS ({ "zwei", "drei", "vier", "fuenf", "sechs", "sieben", "acht" })


// Hilfsfunktion, die bei kaputten Exits eine Notrettung betreibt, aber
// trotzdem auf Debug eine Meldung macht.
static mapping rescueExit()
{
  catch(raise_error(sprintf(
	  "room/exits.c: Forgotten ::create()? "
	  "P_EXITS in %O is 0!\n", this_object()));publish); 

  return ([:2]);
}


static mapping _set_exits( mapping map_ldfied ) 
{
    if( mappingp(map_ldfied) )
        return Set( P_EXITS, map_ldfied );
    return 0;
}


static mapping _query_exits() 
{
    if( (!previous_object() || object_name(previous_object()) != DOOR_MASTER)
        && QueryProp(P_DOOR_INFOS) )
        call_other( DOOR_MASTER, "init_doors" );

    mapping exits = Query(P_EXITS) || rescueExit();

    return filter(exits, function int (string key, mixed val)
        {return stringp(val[0]);} );
}


static int _set_special_exits( mapping map_ldfied )
{
    return -1;
}


static mapping _query_special_exits() 
{
    mapping exits = Query(P_EXITS) || rescueExit();

    return filter(exits, function int (string key, mixed val)
        {return closurep(val[0]);} );
}


void reset()
{}


protected void create()
{
  offerHook(H_HOOK_EXIT_USE, 1);
  SetProp( P_EXITS, ([:2]) );
}

protected void create_super() {
  set_next_reset(-1);
}

protected void _AddExit(string|string* cmd, string|closure room,
                        string message)
{
  mapping exita;

  exita = Query(P_EXITS) || rescueExit();

  if ( !closurep(room) )
  {
    object router;

    room = _MakePath(room);

    if ( !clonep(this_object()) && objectp(router = find_object(ROUTER)) )
    {
      router->RegisterExit( object_name(this_object()), cmd, room );
    }
  }

  if( stringp(cmd) )
  {
    exita += ([ cmd : room; message ]);
  }
  else
  {
    foreach(string c : cmd)
    {
      if (stringp(c))
        exita += ([ c : room; message ]);
    }
  }

  Set( P_EXITS, exita );
}

void AddExit(string|string* cmd, closure|string dest)
{
  string msg;
  if ( stringp(dest) )
  {
    int s;
    if( (s = member(dest, '#')) != -1 )
    {
      msg  = dest[0..s-1];
      dest = dest[s+1..];
    }
  }
  _AddExit(cmd, dest, msg);
}

void RemoveExit(string|string* cmd )
{
    mapping exita;

    if ( !cmd ) {
        SetProp(P_EXITS, ([:2]) );
        return;
    }

    if ( stringp(cmd) )
        cmd = ({ cmd });

    exita = Query(P_EXITS, F_VALUE) || rescueExit();
    foreach(string c : cmd)
      m_delete( exita, c );

    Set( P_EXITS, exita, F_VALUE );
}


void AddSpecialExit(string|string* cmd, string|closure functionname )
{

    if ( stringp(functionname) )
        functionname = symbol_function( functionname, this_object() );

    if ( !closurep(functionname) )
    {
        catch(raise_error(sprintf( "method %O doesn't exist\n",
                          functionname)); publish);
        return;
    }

    AddExit( cmd, functionname );
}


void RemoveSpecialExit(string|string* cmd)
{
    RemoveExit( cmd );
}


varargs string GetExits( object viewer ) 
{
    string *indices, *hidden;
    string exits;

    if ( QueryProp(P_DOOR_INFOS) )
        call_other( DOOR_MASTER, "init_doors" );

    indices = m_indices( Query(P_EXITS) || rescueExit() );
    
    if ( pointerp(hidden = QueryProp(P_HIDE_EXITS)) )
        indices -= hidden;

    int n=sizeof(indices);
    switch (n) {
    case 0:
        return "Es gibt keine sichtbaren Ausgaenge.\n";
        
    case 1:
        return "Es gibt einen sichtbaren Ausgang: " + indices[0] + ".\n";
        
    case 2: case 3: case 4: case 5: case 6: case 7: case 8:
        exits = "Es gibt " + NUMBERS[n-2] + " sichtbare Ausgaenge: ";
        break;
        
    default:
        exits = "Es gibt viele sichtbare Ausgaenge: ";
    }
    exits += CountUp(indices);
    return break_string( exits+".", 78 );
}


// Richtungsbefehle nur interpretieren, wenn der Spieler *im* Raum steht und
// nicht davor (Transporter etc.)/o
void init()
{
    if ( environment(this_player()) == this_object() )
        add_action( "_normalfunction", "", 1 );
}


/* not only normal exits are handled here */

int _normalfunction()
{
  int ret;
  mapping exits = Query(P_EXITS, F_VALUE) || ([:3]);
  if (!member(exits,query_verb()))
    return 0;

  string verb = query_verb();
  string destroom = exits[query_verb(),0];
  string message = exits[query_verb(),1];

  mixed hres = HookFlow(H_HOOK_EXIT_USE, ({verb, destroom, message}));
  if(hres && pointerp(hres) && sizeof(hres)>H_RETDATA)
  {
    if(hres[H_RETCODE]==H_CANCELLED)
    {
      return 1;
    }
    else if(hres[H_RETCODE]==H_ALTERED
            && pointerp(hres[H_RETDATA])
            && sizeof(hres[H_RETDATA]) >= 3)
    {
      <string|closure>* hdata = hres[H_RETDATA];
      if (!stringp(hdata[0])
          || (!stringp(hdata[1]) && !closurep(hdata[1]))
          || (hdata[2] && !stringp(hdata[2])) )
        raise_error(sprintf("Invalide Daten aus H_HOOK_EXIT_USE: %.150O\n",
                            hdata));
      verb = hdata[0];
      destroom = hdata[1];
      message = hdata[2];
    }
  }

  if( closurep(destroom) )
  {
    ret = funcall( destroom, verb );

    if(ret==MOVE_OK)
    {
      GiveEP( EP_EXIT, verb );
    }

    return ret;
  }

  if (!stringp(message))
  {
    if( member( ({ "sueden", "suedwesten", "westen","nordwesten", "norden",
        "nordosten", "osten","suedosten" }), verb ) != -1 )
    {
      message = "nach " + capitalize(verb);
    }
    else if ( member( ({ "oben", "unten" }), verb ) != -1 )
    {
      message = "nach " + verb;
    }
    else
    {
      message = verb;
    }
  }

  ret = this_player()->move( destroom, M_GO, message );

  if (ret==MOVE_OK)
  {
    GiveEP( EP_EXIT, verb );
  }

  return ret;
}

static string _MakePath( string str )
{
  string *comp;

  comp = explode( object_name(this_object()), "/" ) - ({""});
  
   switch( str[0] ){
   case '.':
       str = "/" + implode( comp[0..<2], "/" ) + "/" + str;
       break;
       
   case '~':
       str = "/" + comp[0] + "/" + (comp[0] == "d" ? comp[1] + "/" : "")
           +REAL_UID(this_object()) + str[1..];
       break;
   }
   
   return MASTER->_get_path( str, getuid(this_object()) );
}

