package w3c.rtsp.client;

import java.io.*;
import java.util.*;
import java.net.*;
import java.awt.*;
import w3c.rtsp.common.*;

public class RtspReceive extends Thread  {

   protected InputStream input=null;
   protected PrintWriter output=null;
   protected boolean present=false;
   protected RtspReply reply=null;
   protected RtspRequest request=null;

   public RtspReceive (InputStream input,PrintWriter output){
     this.input=input;
     this.output=output;
   }

   protected  synchronized void WaitMessagePresent(){
     while (present==false){
       try{
	 wait();
       } 
       catch(InterruptedException E){
       }
     }
   }

  //wait for the reply of the associated request.

   public synchronized  RtspReply NotifyRequest(RtspRequest request){
     this.request=request;
     this.reply=null;
     try{
     while(reply==null)
       wait();
     }catch(InterruptedException E){
       System.out.print("\n INTERRUPT ERROR : "+E.getMessage());
       E.printStackTrace();
     }
     return reply;
   }

  //receive and recreate the object message.

   public  void DoReceiveMessage() {  
     try {
       boolean msg=true;
       int ch=-1;
       char line[]=null;
       String length=null;

       // Read next line of input: reading header.

       int lineSize=0;
       line=new char[1024];
       while(msg==true)
	 switch(ch = input.read()) {
	 case -1:{
	   System.out.println("\nSORRY : SERVER DEAD :");
	   msg=false;
	   System.exit(0);
	   //	   break ;
	 }
	 case '\r':
	   input.mark(5);
	   if((ch=input.read())=='\n')
	     if((ch=input.read())=='\r')
	       if((ch=input.read())=='\n'){
		 msg=false;
		 break;
	       }
	       else{
		 input.reset();
		 break;
	       }
	     else{
	       System.out.print("\r\n");
	       line[lineSize++]='\r';
	       line[lineSize++]='\n';
	     }
	 default:
	   System.out.print(new Character((char) ch));
	   line[lineSize++]=(char)ch;
	   break;
	 }

       String stline=new String(line,0,lineSize);
       StringTokenizer l=new StringTokenizer(stline);
       while(l.hasMoreTokens()){
	 try{
	   if(l.nextToken().equals("Content-Length:"))
	     length=l.nextToken();
	 }catch(NumberFormatException E){
	   
	 }
       }
       int len=-1;
       try{
	   len=Integer.parseInt(length);
       }catch(NumberFormatException E){
	 
       }
       
       // create the space to receive the body.
       byte [] buff=null;
       try{
	 buff=new byte[len];
       }catch(NegativeArraySizeException E){
	 buff=new byte[10];
	 len=2;
       }
       for (int j = 0 ; j < len ; ) {
	 j += input.read(buff, j, len-j);
       }
       String mess = new String(buff, 0, len);
       System.out.println("\n"+mess);
       msg=true;

       //Can treat the server request's or the reply's 
       	  System.out.println("--------------------------------------");

       if(isWhat(stline)==2){
	 RtspRequest SRq=new RtspRequest(stline,mess);
	 TreatRequest(SRq);
	 stline=null;
       }
       //we have received a reply.

       if(isWhat(stline)==1){
	 RtspReply SRp=new RtspReply(stline,mess);
	 stline=null;

	 //if it's the expected one's wake up all.

	 if(this.request.requestline.getSeqNo()==SRp.getStatusLine().getSeqNo()){
	   synchronized(this) {
	     this.reply=SRp;
	     notifyAll();
	   }
	 }
       }
     }
     catch(IOException E){
       System.err.println("\n"+"error socket : ");
       E.printStackTrace();
       this.stop();
     } catch(ArrayIndexOutOfBoundsException E){
       E.printStackTrace();
       System.exit(1);
     }  
   }
  
  public void run(){
    while (true)
      // try{
	DoReceiveMessage();
    //}catch(SocketException E){
    //	System.out.println("\nIN THE RUN");
    // }
  }

  //return 1 if it's a reply, 2 if it's request and else -1.

  public int isWhat(String message){
    int result=-1;
    if((message != null) && message.startsWith("RTSP"))
      result=1;
    else
      result=2;
    
    return result; 
  }

  //here we treat the SERVER request.

  public void TreatRequest(RtspRequest request){

    // System.out.print("\nCLIENT has got : "+request.requestline.getMethod()+"\n");
    // System.out.print("\nCLIENT has got : "+request.requestline.getUrlRequest()+"\n");
    
  //here,we have to make the reply.
    
    RtspReply reply=new RtspReply(new StatusLine("RTSP/1.1",
						 200,
						 request.requestline.getSeqNo(),
						 "CLIENTREASONS"),
				  new GeneralHeader(new Date()),
				  new ResponseHeader("CLIENTLOCATION"),
				  new EntityHeader("CLIENTENCODING"),
				  new TransportHeader(),
				  "CLIENT BODY  MESSAGE");
    reply.emit(output);

  }
}
