package serwer;

import java.net.*;
import java.util.*;
import java.io.*;
/**
 * @author w21826 Piotr Lezon 8MKDR-TI-SZL
 *
 */

public class Serwer implements Runnable, Stale
/**
 * Implementujemy interfejsy: Runnable (do tworzenia wątków) oraz Stale (tam są przechowywane stale uzywane w programie)
 */
{
	
	ServerSocket ss;
	// Socket serwerowy
	Socket socket;
	// Socket tworzony po polaczeniu klienta
	public ArrayList <Klient> userlist;
	// Lista podlaczonych klientow
	Thread thread;
	//glowny watek programu
	private DataOutputStream dataoutputstream;
	
	public Serwer()
	{
		try 
		{												
			ss = new ServerSocket(port);
			userlist = new ArrayList<Klient>();
			//System.out.println(userlist.size());
			//tworzymy liste do obslugi uzytwkonikow
			//System.out.println("Uruchomiono serwer na " + InetAddress.getLocalHost() + " na porcie " + ss.getLocalPort());
		}
		catch(IOException e) 
		{ 
			System.err.println("Nie mozna uruchomic serwera na porcie " +port);
		}



		thread = new Thread(this);
		thread.start();
		//startujemy glowny watek programu
	}			
	
	public void run()
	{
		while(thread != null)
		{
			try
			{
				//System.out.println(ss);
				//System.out.println(socket);
				//socket=ss.accept();
				//System.out.println("Nowe polaczenie z " + socket.getInetAddress().getHostAddress() +" z portu " +socket.getPort());
				SerwerWatek watek = new SerwerWatek(this,ss.accept());
				//System.out.println("S@60 "+watek.socket);
				//akceptujemy polaczenie i tworzymy nowy watek do obslugi polaczenia
				thread.sleep(THREAD_SLEEP_TIME);	
			}
			catch(Exception e) 	
			{ 
				e.printStackTrace();
			}
			
		}	
	}
	
	private void WyslijDoKlienta(Socket cs,String wiadomosc)
	{
		//System.out.println("S@73 "+cs);
		//System.out.println("S@74 "+wiadomosc);
		try 
			{
				dataoutputstream = new DataOutputStream(cs.getOutputStream());	
				dataoutputstream.write(new String(wiadomosc+"\r\n").getBytes());
			}
			catch(IOException e) 
			{ 
				System.err.println("Nie udalo sie wyslac wiadomosci do klienta");
			}
	}
	

	private Klient ZnajdzUzytkownika(String nick)
	//metoda zwracajaca objekt klienta
	{
		for(int i=0;i<userlist.size();i++)
		{
			if(userlist.get(i).getUserName().equals(nick))
			{
				//System.out.println("Nick " + nick + " znajduje sie na userlist na pozycji " + i);
				return userlist.get(i);
			}
				
		}
		return null;
	}
	
	private boolean Polaczony(String nick)
	//metoda sprawdzajaca czy dany klient jest podlaczony - czy istnieje na liscie userlist
	{		
		if(ZnajdzUzytkownika(nick) != null)
		{
			System.out.println("Uzytkownik o nicku " + nick + " jest polaczony");
			return true;
		}
		else
		{
			System.out.println("Nie ma nicka " + nick +",ok!");
			return false;
		}
	}
	

	private int ZwrocIndeks(String nick)
	//funkcja zwracajaca indeks uzytkownika na liscie userlist
	{
		for(int i = 0; i < userlist.size();i++)
		{
			if(userlist.get(i).getUserName().equals(nick))
			{
				//System.out.println("Uzytkownik " + nick + " istnieje na liscie userlist pod indeksem " +i );
				return i;	
			}
		}
		//System.out.println("Nie ma takiego uzytkownika!");
		return -1;
	}

	
	protected void DodajUzytkownika(Socket cs,String nick)
	//dodawanie nowego uzytkownika do listy userlist
	{
			//System.out.println(cs);
			//System.out.println(nick);
			if(Polaczony(nick))
			//jezeli ktos juz jest z takim nickiem, wysylany jest komunikat do klienta
			{
				WyslijDoKlienta(cs,"EXIS ");
			}
			else
			{
			userlist.add(new Klient(cs,nick));
			System.out.println("Nowy podlaczony, " + cs + " " + nick);
			//utworzenie nowego obiektu klienta i dodanie do userlist
			}
												
	}
	
	
	protected void UsunUzytkownika(String nick)
	//usuwanie klienta z listy userlist oraz wysylanie komunikatu do pozostalych klientow
	{
		//Klient removeKlient = ZnajdzUzytkownika(nick);
		if(ZwrocIndeks(nick) != -1)
		{
			userlist.remove(ZwrocIndeks(nick));	
			System.out.println("Usunieto uzytkownika " + nick);
			userlist.trimToSize();

			for(int i=0; i<userlist.size();i++)
			{
				WyslijDoKlienta(userlist.get(i).getSocket(),"REMO "+nick);
			}			
		}			
	}
	
	/*
	protected void UsunUzytkownika_ERR(Socket cs)
	{
			for(int i=0;i<userlist.size();i++)
			{
				if(userlist.get(i).getSocket().equals(cs))
				{
					userlist.remove(userlist.get(i));	
					userlist.trimToSize();		
																	 
					for(int j=0;j<userlist.size();j++)
					//wysylamy wszystkim wiadomosc o rozlaczeniu sie uzytkownika
					{
						WyslijDoKlienta(userlist.get(j).getSocket(),"REMO "+userlist.get(i).getUserName());
					}
					
				}	
			}
	}
		*/
	
	protected void WyslijMM(String tresc,String nick)
	{
			for(int i=0;i<userlist.size();i++)
			//wysylanie wiadomosci
			{
				System.out.println("S@194 " + userlist.size());
				/*if(userlist.get(i).getUserName().compareToIgnoreCase(nick) != 0);
					//nie wysylamy do nadawcy, bo po co? ;)
				{			
					//System.out.println(userlist.get(i).getUserName() + " " + userlist.get(i).getSocket());
					//System.out.println
				*/

					WyslijDoKlienta(userlist.get(i).getSocket(),"MESS "+nick+":"+tresc);	
				//}
			}

	}

	
	public static void main(String[] args) 
	{		
		new Serwer();
	}
	
}
