/** 
 * publishersServer.java
 *
 * Description:	
 * @author			daassi
 * @version			
 */

package publishersServer;

import java.io.*;
import java.util.Vector;

import java.net.*;

public class publishersServer 
{
   Socket mainBus = null, publisherDeviceSocket = null, newSurfaceClient = null;  
   	
   ServerSocket publisherDriverSocket = null, mainBusSocket = null,newSurfaceServer = null;
		   
   PrintWriter publisherDeviceOut = null, newSurfaceOut = null;
   BufferedReader publisherDeviceIn = null, newSurfaceIn = null;
      
   int nextChanalID = 1901 ; 
          
   boolean sameDataSpace = true ;
   boolean dataSpaceHaveBeenInit = false ;
   Vector surfacesNames = new Vector();
   Vector surfacesDataSpaces = new Vector();
   Vector surfacesAdresses = new Vector();
   Vector currentSurfacesOut = new Vector();
   Vector currentSurfacesIn = new Vector();   
   
   Vector dataSpacesInformationsFromDevice = new Vector();
      
   int currentSurfaceID = 0;
   int nextThreadID = 0 ;
   
   boolean synchronizedNavigation = true ;    
       
   int techniqueID = 2 ;   
    
	public publishersServer() 
	{	  
	  try 
        {
           setUpSurfacesServers() ;
        } 
        catch (IOException e)
        {
          System.err.println("Could not setUp Surfaces Servers.");
          System.exit(1);
        }	      
	 }
      
    private void setUpSurfacesServers() throws IOException
    {  
       listenToNewConnections newConnection =  null ; 
       fromPublisherDeviceToSurfaces  surfaceThread = null;	
             
        try 
        {
            publisherDriverSocket = new ServerSocket(1900);            
            mainBusSocket = new ServerSocket(1901);           
                      
        } 
        catch (IOException e)
        {
          System.err.println("Could not listen to the port: 1900 or 1901.");
          System.exit(1);
        }        
        
        System.err.println("mainBusSocket wait surface to be connected");
               
        try
        {
          publisherDeviceSocket = publisherDriverSocket.accept();                                 
                                  
        } 
        catch (IOException e)
        {
            System.err.println("Accept failed.");
            System.exit(1);
        }        
                                     
        publisherDeviceOut = new PrintWriter(publisherDeviceSocket.getOutputStream(), true);
        publisherDeviceIn = new BufferedReader(new InputStreamReader(publisherDeviceSocket.getInputStream()));
              
        newConnection =  new listenToNewConnections (Integer.toString(surfacesAdresses.size())) ;
        newConnection.start() ;
        
        surfaceThread =  new fromPublisherDeviceToSurfaces ("fromDeviceToSurfaces") ;
        surfaceThread.start() ;                      
             
    }
 
 
  public class listenToNewConnections extends Thread 
  {
    fromSurfaceToPublisherDevice newSurfaceThread = null ;     
           
    public listenToNewConnections(String processName)
    { 
        super(processName);
      
    } 
    
    public void run() 
    {       
      
      while (true)
      {
         try
         {                             
           newSurfaceClient = mainBusSocket.accept(); 
                                        
           newSurfaceOut = new PrintWriter(newSurfaceClient.getOutputStream(), true);
           newSurfaceIn = new BufferedReader(new InputStreamReader(newSurfaceClient.getInputStream()));
                                                           
           currentSurfacesOut.add(newSurfaceOut);                    
                                       
           currentSurfacesIn.add(newSurfaceIn);                    
                                        
           surfacesAdresses.add(newSurfaceServer);
           
           newSurfaceThread =  new fromSurfaceToPublisherDevice (Integer.toString(nextThreadID)) ;
           newSurfaceThread.start() ;            
           
           System.out.println("one thread has been created !!");
              
         } 
            catch (IOException e)
            {
              System.err.println("Could not listen to the port: 1900 or 1901.");
              System.exit(1);
            }
      }
    
    }
    
  }    
 
  public class fromPublisherDeviceToSurfaces extends Thread 
  {
     String oneLineFromDevice = "", oneLineToTimeDevice ="";  
     
    // int newSurfaceID = - 10 ;
     
    public fromPublisherDeviceToSurfaces(String threadName)
    {
        super(threadName);
    }
        
    public void run ( )
    { 
      Vector informationsFromDevice = null;
           
      while (true)
      {   
        if (publisherDeviceSocket!= null) 
        {             
          try
          {         
             oneLineFromDevice = (publisherDeviceIn.readLine());         
            // publisherDeviceOut.println(oneLineToTimeDevice);                    
             
             System.out.println("in the server !!");
             System.out.println(oneLineFromDevice);
             
             ((PrintWriter)currentSurfacesOut.elementAt(currentSurfaceID)).println(oneLineFromDevice); 

             
           }
           catch (IOException e)
           {
             System.out.println("An exeption !!");
           
           }
        }         
     
     }
    
    } 
    
  }   
   
  public class fromSurfaceToPublisherDevice extends Thread 
  {
     String oneLineFromThisSurface = "";     
     int surfaceID = -10 ;
     String surfaceName = "";  
     boolean goOn = false ;   
     BufferedReader currentBufferedReader = null ;
        
    public fromSurfaceToPublisherDevice(String processName)
    { 
        super(processName);
        surfaceID = Integer.parseInt(processName); 
        
        if (surfaceID >= 0)        
        {
           currentBufferedReader = ((BufferedReader)currentSurfacesIn.elementAt(surfaceID)) ; 
           
           nextThreadID += 1 ;          
           goOn = true ;        
        }      
    } 
    
    public void run() 
    {            
      while (goOn)
      {         
        if(currentBufferedReader != null)
        {            
          try
          {             
              oneLineFromThisSurface = currentBufferedReader.readLine(); 
              
              publisherDeviceOut.println(oneLineFromThisSurface);
              
                                           
              if (oneLineFromThisSurface != null)
              {
                if ((oneLineFromThisSurface.equals("startSending"))) 
                {                  
                  oneLineFromThisSurface = currentBufferedReader.readLine();
                  surfaceName = oneLineFromThisSurface ;
                  
                  surfacesNames.add(surfaceName);                                                                       
                  processNewDataSpace (surfaceName, surfaceID) ;
                                   
                }
                else
                if (surfaceID == currentSurfaceID)
                {
                    publisherDeviceOut.println(oneLineFromThisSurface);                                                       
                }                            
             
              }                   
             
           }
           catch (IOException e)
           {
             System.out.println("An exeption !!");
           
           }
        }         
     }
    
    }
    
  }     
   
   public void processNewDataSpace (String surfaceNameID, int bufferedReaderID) throws IOException
   {
       String oneLineFromSurface = "" ; 
            
       BufferedReader in = ((BufferedReader)currentSurfacesIn.elementAt(bufferedReaderID)) ;       
                    
       oneLineFromSurface = in.readLine();
                          
       while (!(oneLineFromSurface.equals("endSendVal")))
       { 
          publisherDeviceOut.println(oneLineFromSurface);
                         
          oneLineFromSurface = in.readLine();                                                 
       }     
       
   }
	
	// Main entry point
	static public void main(String[] args) {
		new publishersServer();
	}
	
}
