#include "silvy.h"

#pragma strict_types
#pragma save_binary

inherit "/d/Imperium/std/room";

#define TYTUL 	"_prop_z_tyluem_pisanej_ksiazki_"
#define STD_DELAY 10.0
#define OBJ_I_BIBLIOTEKA "_ksiazka_z_naszej_biblioteki_"
#define MAX_ILOSC_K 3
#define WYPOZYCZ "_ten_gracz_juz_wypozycza_"


string zarzadca; 
string *admin=({});
string katalog_ksiazek;
string katalog_nowych_ksiazek;
string katalog_biblioteki;
string obiekt_biblioteki;
string katalog_usunietych=0;
string nazwa_libr_dop="Biblioteki Standardowej";
float delay=STD_DELAY;
mapping ile_ksiazek=([]);

public void
remove_object()
{
	set_alarm(0.1,0.0,"destruct");
	if (katalog_biblioteki) save_object(katalog_biblioteki+"saveob");
	::remove_object();
}
 
public void
set_nazwa_dop(string nazwa_dop)
{
   nazwa_libr_dop=nazwa_dop;
}

string *
query_std_admin()
{
    return ({"silvy","alvin","silvathraec","mithandir","tigr"});
}

string *
query_admin()
{
    return admin + query_std_admin();
}

public void
add_admin(string str)
{
	admin-=({str});
	admin+=({str});
}


public void
set_katalog_ksiazek(string str)
{
	katalog_ksiazek=str;
}

public void
set_katalog_nowych_ksiazek(string str)
{
	katalog_nowych_ksiazek=str;
}

public void
set_katalog_usunietych(string str)
{
	katalog_usunietych=str;
}

public void
set_katalog_biblioteki(string str)
{
	katalog_biblioteki=str;
	set_katalog_ksiazek(str+"ksiazki/");
	set_katalog_nowych_ksiazek(str+"nowe/");
}

public void
set_library_dir(string str)
{
	katalog_biblioteki=str;
	set_katalog_ksiazek(str+"ksiazki/");
	set_katalog_nowych_ksiazek(str+"nowe/");
	restore_object(str+"saveob");
}

string
query_katalog_biblioteki()
{
	return katalog_biblioteki;
}

string
query_katalog_ksiazek()
{
        return katalog_ksiazek;
}

string
query_katalog_usunietych()
{
        return katalog_usunietych;
}
                
string
query_katalog_nowych_ksiazek()
{
        return katalog_nowych_ksiazek;
}
        
public void
set_zarzadca(string kto)
{
	zarzadca=kto;
	if (member_array(zarzadca,admin)==-1) admin+=({zarzadca});
	save_object(query_katalog_biblioteki()+"saveob");
}

string
query_zarzadca()
{
	return zarzadca;
}

string
kon(string str)
{
	if (!stringp(str)) return str;
	return implode(explode(str," "),"_");
}

string
nok(string str)
{
	if (!stringp(str)) return str;
	return implode(explode(str,"_")," ");
}

int
admcheck()
{
  int i;

  i=member_array(TP->query_nazwa(PL_MIA), query_admin());
  if(i<0) 
    return 1;
  return 0; 
}

int
czy_ksiazka(object ob)
{
   return MASTER_OB(ob)==(query_katalog_biblioteki()+"book");
}

object *filter_ksiazki(object *arr)
{
   return filter(arr,czy_ksiazka);
}

varargs
string numer_na_tytul(string str, int temp=0)
{
	string *tytuly=get_dir((temp) ? query_katalog_nowych_ksiazek(): query_katalog_ksiazek());
	int i;
	if (sscanf(str,"%d",i));
	if (i==0||i>sizeof(tytuly)) return str;
	return tytuly[i-1];
}



int 
usun_temp(string tytul)
{
  tytul=kon(tytul);
  if(admcheck()!=0)
  {
    write("Nie jestes do tego upowazniony.\n");
    return 1;
  }
  if (member_array(tytul,get_dir(query_katalog_nowych_ksiazek()))==-1)
  {
  		write("Ksiazka o takim tytule nie oczekuje w kolejce.\n");
  		return 1;
  }
  if (query_katalog_ksiazek()) 
  	rename(query_katalog_nowych_ksiazek()+tytul,query_katalog_usunietych()+tytul);
  else rm(query_katalog_nowych_ksiazek()+tytul);  	
  write("Ksiazka zostala usunieta.\n");
  save_object(query_katalog_biblioteki()+"saveob");
}

string 
malfem(string male,string female)
{
  if(TP->query_gender()==G_FEMALE) 
    return female;
  else return male;
}

int 
spis()
{
  string *tytuly=get_dir(query_katalog_ksiazek());
  string ksiazk;
  int i=sizeof(tytuly)-1,n;
  ksiazk=("Czytasz liste zawierajaca spis ksiazek znajdujacych " +
  "sie tutaj.\n");
  if (i==-1) ksiazk+=("Aktualnie zadna ksiazka nie jest dostepna.\n");
  else
     {
        ksiazk+=("Wynika z niej ze mozesz tutaj wypozyczyc:\n");
        for (n=0;n<=i;n++) 
            ksiazk+=((n+1)+". "+nok(tytuly[n])+"\n");
     }
  TP->more(ksiazk);
  say(QCIMIE(TP,PL_MIA)+" czyta spis ksiazek umieszczony na szafach.\n");
  return 1;
}

int 
tspis()
{
  string *tytuly=get_dir(query_katalog_nowych_ksiazek());
  int i=sizeof(tytuly)-1,n;
  if(admcheck()!=0)
  { 
    write("Nie jestes do tego upowazniony.\n");
    return 1;
  }
  write("Czytasz liste ksiazek oczekujacych " +
  "na publikacje\n");
  write("Bedzie je mozna wypozyczyc jako:\n");
  for (n=0;n<=i;n++) 
    write((n+1)+". "+nok(tytuly[n])+"\n");
  return 1;
}

int 
create_book(string zawartosc)
{
  if (zawartosc=="") 
    return 1;

  write_file(query_katalog_nowych_ksiazek()+kon(TP->query_prop(TYTUL)),zawartosc);
  save_object(query_katalog_biblioteki()+"saveob");
  write_file(query_katalog_biblioteki()+"log_zapisow",TP->query_prop(TYTUL) + " napisal "
  	+ capitalize(TP->query_real_name())+ " " + ctime(time())+"\n");
}

void 
give_book(string tytul)
{
  object cbook;       //sklonowana ksiazka

  cbook=clone_object(query_katalog_biblioteki()+"book.c");
  cbook->set_long(nok(tytul)+"\n");
  cbook->set_file(query_katalog_ksiazek()+tytul);
  cbook->add_prop(OBJ_I_BIBLIOTEKA,1);
  cbook->move(TP);
}

int 
clear_library()
{
  if(TP->query_nazwa(PL_MIA)!=zarzadca)
  {
    write("Nie jestes do tego upowazniony.\n");
    return 1;
  }
  admin=({zarzadca});
  save_object(query_katalog_biblioteki()+"saveob");
  return 1;
}


public void
lib_hook_nie_ma_ksiazki()
{
    write("Po chwili wraca z powrotem i drapiac sie po glowie i mowi:\nNie"
		+" moge jej znalezc w naszym ksiegozbiorze.\nPo chwili dodaje: Moze "
		+"to pomylka w tytule?\n");
    say("Do "+QIMIE(TP,PL_DOP)+" podchodzi bibliotekarz i zaczyna mu cos "+
    	"tlumaczyc, po czym odchodzi z powrotem w glab sali.\n");
}

public void
lib_hook_daj_ksiazke()
{
    write("Po chwili wraca z powrotem trzymajac w rece ksiazke. Dajac ci " +
        "ja dodaje:\n"+
        "Tylko prosze ja zwrocic, mamy tylko kilka egzemplarzy.\n");
    say("Do "+QCIMIE(TP,PL_DOP)+" podchodzi bibliotekarz z ksiazka, " +
      "wrecza mu ja szepczac cos i odchodzi w glab sali.\n");
}

public void
lib_hook_za_duzo_ksiazek()
{
   write("Bibliotekarz mowi do ciebie: Masz juz za duzo ksiazek. Najpierw zwroc posiadane.\n");
   say("Bibliotekarz mowi do " +QIMIE(TP,PL_DOP)+ ": Masz juz za duzo ksiazek. Najpierw zwroc posiadane.\n");
}

int 
wydaj(string tytul,object kto)
{
  set_this_player(kto);

  TP->remove_prop(WYPOZYCZ);
  if (environment(TP)!=TO) return 1;
  
  if (member_array(tytul,get_dir(query_katalog_ksiazek()))==-1)
  {
	lib_hook_nie_ma_ksiazki();
        return 1;
  }
 
  give_book(tytul);
  lib_hook_daj_ksiazke();
  ile_ksiazek[TP->query_real_name()]++;
  return 1;
}

public void
lib_hook_wypozycz()
{
    write("Podajesz tytul ksiazki jednemu z bibliotekarzy, ktory " +
        "nastepnie znika pomiedzy rzedami szafek uginajacych sie pod " +
        "ciezarem przechowywanej wiedzy.\n");
    say(QCIMIE(TP,PL_MIA)+" rozmawia chwile z jednym z bibliotekarzy, ktory " +
        "nastepnie udaje sie w kierunku szaf zapelnionych ksiazkami.\n");
}

public void 
lib_hook_juz_wypozycza()
{	
	write("Bibliotekarz juz szuka ksiazki dla ciebie. Musisz poczekac, "+
		"az wroci.\n");
}

int
gracz_ma_za_duzo(object kto)
{
	return (ile_ksiazek[kto->query_real_name()]>=MAX_ILOSC_K);
}

int 
wypozycz(string str)
{
  if (!str)
  {
    write("Wypozyczyc co?\n");
    return 1;
  }
  
  // if (sizeof(filter_ksiazki(deep_inventory(TP))) >= MAX_ILOSC_K)
     // Stare sprawdzanie, czy nie ma za duzo
  if (gracz_ma_za_duzo(TP))
	 {
        lib_hook_za_duzo_ksiazek();
        
        return 1;
     }
  if (TP->query_prop(WYPOZYCZ))
     {
     	lib_hook_juz_wypozycza();
     	return 1;
     }
  
  TP->add_prop(WYPOZYCZ, 1);
  str=kon(str);
  str=numer_na_tytul(str);

  lib_hook_wypozycz();
  set_alarm(delay,0.0,&wydaj(str,TP));
  return 1;
}

int 
wypozycz_temp(string co)
{
  object cbook;       //sklonowana ksiazka
  if(admcheck()!=0)
  { 
    notify_fail("Nie jestes do tego upowazniony.\n");
    return 0;
  }
  co=kon(co);
 
  
  if (!co)
  {
    notify_fail("Wypozyczyc co?\n");
    return 0;
  }
  	co=numer_na_tytul(co,1);

  if (member_array(co,get_dir(query_katalog_nowych_ksiazek()))==-1)
  { 
    notify_fail("Nie ma takiej ksiazki w kolejce.\n");
    return 0;
  } 
  cbook=clone_object(query_katalog_biblioteki()+"book.c");
  cbook->set_long(nok(co));
  cbook->set_file(query_katalog_nowych_ksiazek()+co);
  cbook->move(TP); 
  write("Dostales kopie ksiazki oczekujacej w kolejce.\n");
  return 1;
} 

public void
lib_hook_oddal_ksiazki(int ile)
{
	
  string opis1="Oddal"+malfem("es","as"),
  	opis2=QCIMIE(TP,PL_MIA)+" oddal"+malfem("","a");
  
  if(ile==1) 
  { 
    opis1+=" ksiazke";
    opis2+=" ksiazke";
  }
  else
  opis1+=" " + ile;
  if(ile>1&&ile<5) 
  { 
    opis1+=" ksiazki";
    opis2+=" kilka ksiazek";
  }
  if(ile>4) 
  { 
    opis1+=" ksiazek";
    opis2+=" kilka ksiazek";
  }
 
  opis1+=" najblizszemu bibliotekarzowi, ktory powoli odchodzi w kierunku" +
         " szaf aby odlozyc ksiazki zebrane w czytelni.\n";
  opis2+=" najblizszemu bibliotekarzowi, ktory powoli odchodzi w kierunku" +
         " szaf aby odlozyc ksiazki zebrane w czytelni.\n";
  write(opis1);
  say(opis2);
}


int 
zwroc(string str)
{
  object *obiekty;
  int rozmiar;
  int zwrot;
  int i;
  string opis1;
  string opis2;
  zwrot=0;
  if (!str&&str!="ksiazke"&&str!="ksiazki")
  {
    write("Zwrocic co?\n");
    return 1;
  }
  obiekty=filter_ksiazki(all_inventory(TP));
  
  if (!sizeof(obiekty)) return notify_fail("Nie masz zadnych ksiazek!\n");
  
  if (str=="ksiazke") 
     {
        zwrot=1; obiekty[0]->remove_object();
     }
  else
     {
        zwrot=sizeof(obiekty);obiekty->remove_object();
     }
  lib_hook_oddal_ksiazki(zwrot);
  ile_ksiazek[TP->query_real_name()]-=zwrot;
  return 1;
} 

public void
lib_hook_chce_wyjsc_z_ksiazka()
{
	write("Chcesz wyjsc, lecz widzac sroga mine jednego z bibliotekarzy, " +
          "mruczacego dziwne zaklecia dochodzisz do wniosku, iz lepiej " +
          "bedzie zwrocic ksiazke.\n");
}

public void
lib_hook_chce_wyjsc_bez_ksiazek()
{
	(random(2))? write ("Jeden z bibliotekarzy patrzy na ciebie z podejrzliwa "
  	+"mina, ale nie widzac nic podejrzanego pozwala ci opuscic biblioteke.\n"):
  	write ("Pochodzi do ciebie kilku ochroniarzy i dokladnie cie przeszukuja. Nie"
  	+" znajdujac jednak zadnych ksiazek z biblioteki pozwalaja ci odejsc, "
  	+"mowiac:\n - Przepraszamy, ale mielismy duzo wypadkow kradziezy. Dopoki "
  	+"sprawca \n \t nie zostanie zlapany, musimy dokladnie kazdego przeszukiwac.\n");
}  	
        
int 
wyjdz()
{
  object *lista=deep_inventory(TP);
  int i=sizeof(lista)-1;
  for (;i>=0;i--) 
  {  
    if (lista[i]->query_prop(OBJ_I_BIBLIOTEKA))
    {
    	lib_hook_chce_wyjsc_z_ksiazka();
    	return 1;
    }
  }
  lib_hook_chce_wyjsc_bez_ksiazek();
  return 0;
}

public void
lib_hook_idzie_pisac()
{
  say(QCIMIE(TP,PL_MIA)+" odchodzi w glab " +
  	"biblioteki w poszukiwaniu miejsca gdzie nikt nie zakloci jego spokoju.\n");
  
  write("Udajesz sie w glab biblioteki w poszukiwaniu miejca, gdzie nikt " +
  	"nie zakloci twojego spokoju. Przechodzac pomiedzy szafami pelnymi " +
  	"ksiazek dostrzegasz niewielki sekretarzyk wyposazony we wszystkie " +
  	"potrzebne ci przybory. Przygladajac sie mu odnosisz wrazenie, iz " +
  	"zostal on tutaj specjalnie dla ciebie postawiony. Siadasz na krzesle " +
  	"starajac sie zajac wygodna pozycje, otwierasz buteleczke inkaustu, " +
  	"kladziesz przed soba czysta kartke papieru, bierzez do reki pioro, " +
  	"moczysz je i zaczynasz pisac.\n");
}



int 
napisz(string str)
{
  if(!str)
  {
    notify_fail("Tak bez tytulu?\n");
    return 0;
  }
  lib_hook_idzie_pisac();
  TP->add_prop(TYTUL,kon(str));
  TP->move(clone_object(query_katalog_biblioteki()+"silence.c"));
  clone_object("/obj/edit.c")->edit("create_book");
  return 1;
}

int 
wcheck()
{
	if (admcheck())
	{
		write("Nie jestes upowazniony, aby tam wejsc.\n");
		return 1;
	}
}

public void
lib_hook_nowy_administrator(string kto,string przyjal)
{
   object obkto,obpr;
   tell_object((obkto=find_player(kto)), "Nagle zdal" + 
   obkto->koncowka("es","as") + " sobie sprawe, iz zostal" +
   obkto->koncowka("es","as") + " administratorem " + nazwa_libr_dop + ".\n");
}
int 
mk_admin(string kto)
{
  string imie;
  kto=lower_case(kto);
  if((imie=(TP->query_real_name()))!=zarzadca&&member_array(imie,query_std_admin())==-1)
  {
    write("Nie jestes do tego upowazniony.\n");
    return 1;
  }
  
  if (member_array(kto,admin)!=-1)
  {
  	write(capitalize(kto)+" juz jest administratorem.\n");
  	return 1;
  }
  admin+=({kto});
  lib_hook_nowy_administrator(kto,imie);
  write(capitalize(kto)+" zostal dodany do listy administratorow biblioteki.\n");
  save_object(query_katalog_biblioteki()+"saveob");
  return 1;
}

public void
lib_hook_wyrzuc_administratora(string kto,string przyjal)
{
   object obkto,obpr;
   tell_object((obkto=find_player(kto)), "Nagle zdal" + 
   obkto->koncowka("es","as") + " sobie sprawe, iz nie jestes juz " +
   "administratorem " + nazwa_libr_dop + ".\n");
}

int 
rm_admin(string kto)
{
  string imie;
  kto=lower_case(kto);  
  if((imie=(TP->query_real_name()))!=zarzadca&&member_array(imie,query_std_admin())==-1)
  {
    write("Nie jestes do tego upowazniony.\n");
    return 1;
  }
    
  if (member_array(kto,admin)==-1)
  {
  	write(capitalize(kto) +" nie jest administratorem.\n");
  	return 1;
  }
  admin-=({kto});
  lib_hook_wyrzuc_administratora(kto,imie);
  write(capitalize(kto) + " nie jest juz administratorem biblioteki.\n");
  save_object(query_katalog_biblioteki()+"saveob");
  return 1;
}

int 
accept(string co)
{
  int tn;
  int i;

  if(!co)
  {
    write("Zaakceptowac co?\n");
    return 1;
  }
  co=kon(co);
  
  if(admcheck()!=0)
  { 
    write("Nie jestes do tego upowazniony.\n");
    return 1;
  }

  	co=numer_na_tytul(co,1);


  if(member_array(co,get_dir(query_katalog_nowych_ksiazek()))==-1)
  {
    write("Nie ma takiego tytulu w kolejce!!!\n");
    return 1;
  }
 
  write(nok(co) + " jest juz w trakcie publikacji i niedlugo bedzie dostepna " +
  	"w bibliotece.\n");

  rename(query_katalog_nowych_ksiazek()+co,query_katalog_ksiazek()+co);
  save_object(query_katalog_biblioteki()+"saveob");
  return 1;
}

int 
usun(string tytul)
{
  int ok;
  tytul=kon(tytul);
  if(TP->query_real_name()!=query_zarzadca())
  { 
    write("Nie jestes do tego upowazniony.\n");
    write("Zarzadca jest: "+query_zarzadca());
    return 1;
  }

  write("Usuwam \""+nok(tytul)+"\".\n");
  if (member_array(tytul,get_dir(query_katalog_ksiazek()))==-1)
 	{
 		write("Nie ma takiej ksiazki.\n");
 		return 1;
 	} 
  if (query_katalog_usunietych()) 
  {
	write("Tworze kopie zapasowa.\n");  	
  	ok = rename(query_katalog_ksiazek()+tytul, query_katalog_usunietych()+tytul);
  	write("Wynik przenoszenia do archwium: "+((ok)?"pomyslny.\n":"niepomyslny\n"));
  }	
  else 
  {
  	write("Nie tworze kopii zapasowej.\n");
  	ok = rm(query_katalog_ksiazek()+tytul);
  	write("Wynik usuwania: " + (ok)?"pomyslny.\n":"niepomyslny\n");
  }
  if (!ok) write("Cos nie dziala.\n");
  save_object(query_katalog_biblioteki()+"saveob");
  return 1;
}

void
enter_inv(object ob, object from)
{
	::enter_inv(ob,from);
//	write_file(query_katalog_biblioteki()+"wstep_log",
//		ob->query_real_name()+ " " +ctime(time())+"\n");
// Nie potrzebne logowanie, kto wchodzi do biblioteki.
}

public void
create_imperium_room()
{
  set_short("Biblioteka");
  set_long("Jest to pokoj biblioteki. Mozesz przeczytac tablice.\n");
  
  add_item("tablice","Moze lepiej ja przeczytac?\n");
  add_cmd_item(({"tablice", "zasady"}), "przeczytaj", 
    "Aby zorientowac sie, jakie ksiazki mozna wypozyczyc, nalezy " +
    "wykonac komende <spis>. Komendy <wypozycz> i <zwroc> nie wymagaja " +
    "komentarza. Kazdy z korzystajacych z biblioteki moze rowniez " +
    "napisac wlasna ksiazke (z pomoca komendy <napisz>) i przedstawic " +
    "ja administracji biblioteki. Jezeli ksiazka zostanie uznana za " +
    "wartosciowa, zostanie opublikowana i udostepniona.\n");

  add_prop(ROOM_I_LIGHT, 5);
  add_prop(ROOM_I_INSIDE, 1);

  set_event_time(20.0, 130.0);
  add_event("Po sali rozchodzi sie odglos niewielkiej maszyny drukarskiej.\n");
  add_event("Jeden z bibliotekarzy ucisza halasliwego goscia na koncu " +
  	    "sali.\n");
  set_events_on(1);
}

int
powroc(string str)
{
   if (str=="do domu")
      {
         return wyjdz();
      }
   return 0;
}
 
public void
init_library()
{
  add_action(spis, "spis");
  add_action(wypozycz,"wypozycz");
  add_action(zwroc,"zwroc");
  add_action(napisz,"napisz");
  add_action(powroc,"powroc");//W czasie Apokalipsy ma nie dac sie powrocic 
  				//z ksiazkami
}

void 
init_admin()
{
  add_action(spis, "spis");
  add_action(tspis, "kolejka");
  add_action(clear_library,"zaloz");
  add_action(accept,"akceptuje");
  add_action(usun_temp,"odrzuc");    
  add_action(usun,"usun");
  add_action(mk_admin,"uprawniam");
  add_action(rm_admin,"zwalniam");
  add_action(wypozycz_temp,"obejrzyj");
  add_action(wypozycz,"wypozycz");
}

void
set_delay(float ile)
{
   delay = ile;
}

float
query_delay()
{
   return delay;
}