package w3c.rtsp.common;

import java.io.*;
import java.util.*;
import java.net.*;
import java.awt.*;


public class RtspReply {

  //we have take the length of messages automaticaly.

  protected StatusLine statusline;
  protected GeneralHeader generalheader;
  protected ResponseHeader responseheader;
  protected EntityHeader entityheader;
  protected TransportHeader transportheader=null;
  protected String BodyMessage = null;

  public RtspReply(StatusLine statusline,
		   GeneralHeader generalheader,
		   ResponseHeader responseheader,
		   EntityHeader entityheader,
		   TransportHeader transportheader,
		   String BodyMessage){
    this.statusline=statusline;
    this.generalheader=generalheader;
    this.responseheader=responseheader;
    this.entityheader=entityheader;
    this.transportheader=transportheader;
    this.BodyMessage=BodyMessage;
  }


 public RtspReply(String status_header,String body){

      String version=null,reasonphrase=null,ce=null,cla=null;
      String al=null,ct=null,e=null,eh=null,lm=null,loc=null,pa=null,pu=null;
      int sn=-1,sc=-1,cl=-1,rp_len=-1;
      boolean EndRequest=true;
      RtspURL urlR=null;
      GeneralHeader gh=new GeneralHeader();
      ResponseHeader rh=new ResponseHeader();
      TransportHeader th=new TransportHeader();
      EntityHeader Eh=new EntityHeader();

      //parsing the status line.

      while(EndRequest==true){
	
	int ver_len=status_header.indexOf(' ');
	//	System.out.println("index : "+ver_len);
	version = status_header.substring(0,ver_len);
	//	System.out.println("\nVersion :"+version);
	int sc_len=status_header.indexOf(' ',ver_len+1);
	//	System.out.println("sc : "+sc_len);
	sc=Integer.parseInt(status_header.substring(ver_len+1,sc_len));
	//	System.out.println("\nSC :"+sc);
	int sn_len=status_header.indexOf(' ',sc_len+1);
	//	System.out.println("index SN: "+sn_len);
	sn= Integer.parseInt(status_header.substring(sc_len+1,sn_len));
	//	System.out.println("\nSN :"+sn);
	rp_len=status_header.indexOf('\n',sn_len+1);
	//	System.out.println("index rp: "+rp_len);
	reasonphrase= status_header.substring(sn_len+1,rp_len-1);
	//	System.out.println("\nREASON PHRASE :"+sn);
	EndRequest=false;
      }
      //parsing the general header,the response header,the entity header and the 
      //transport header.

      int index=rp_len+1;
      
      index=isGeneralHeader(gh,status_header,index);
      
      index=isResponseHeader(rh,status_header,index);
      
      index=isEntityHeader(Eh,status_header,index);
      
      index=isTransportHeader(th,status_header,index);

      //reconstructing the object.
      
      StatusLine stl=new StatusLine(version,sc,sn,reasonphrase);
      
      this.transportheader=new TransportHeader();

      this.statusline=stl;
      this.generalheader=gh;
      this.responseheader=rh;
      this.entityheader=Eh;
      this.transportheader.setTransport(th.getTransport());
      this.transportheader.setPort(th.getPort());
      this.BodyMessage=body;
  }
  //return it if find it.


  public String search(String linerp,String it) {
    int beg_ind=0,end_ind=0;

    if(linerp.lastIndexOf(it)!=-1){
      beg_ind=linerp.indexOf(it)+1+it.length();
      try{
	end_ind=linerp.indexOf("\r\n",beg_ind);
	if(beg_ind>0)
	  return linerp.substring(beg_ind,end_ind);
	else 
	  return null;
      }catch(StringIndexOutOfBoundsException E){
	return linerp.substring(beg_ind);
      }
    }
    else 
      return null;
  }



 public void emit(PrintWriter output){
   //  System.out.println("STATUSLINE");
   statusline.emit(output);
   // System.out.println("GENERAL HEADER");
   generalheader.emit(output);
   // System.out.println("HEADER RESPONSE");
   responseheader.emit(output);
   //System.out.println("ENTITY HEADER");
   entityheader.setContentLength(BodyMessage.length());
   entityheader.emit(output);
   //send the tranport header.
   // System.out.println("TRANSPORT HEADER");
   transportheader.emit(output);
   output.print("\r\n");
   output.print(BodyMessage);
   output.flush();
 }

  public StatusLine getStatusLine(){
    return statusline;
  }

  //a simple test only the version used in the reply.

  public boolean isRtspReply(){
    RtspReply Err;
   return (this.statusline.getVersion().equalsIgnoreCase("RSTP/1.1"));
  }

  public EntityHeader getEntityHeader(){
    return entityheader;
  }

  //parse the contents of the TransportHeader.

  public TransportHeader parseTransportHeader(String myString){
    char trans[]=null,p[]=null,reccord[]=null;
    TransportHeader TH;
    int i=0;
    reccord=myString.toCharArray();
    // System.out.println("\nRECCORD="+reccord);
    // System.out.println("\nLENGTH="+myString.length());
    while(reccord[i]!=';'){
      i++;
    }
    trans=new char[i+1];
    i=0;
    while(reccord[i]!=';'){
      trans[i]=reccord[i];
      i++;
    }
    while(reccord[i++]!='=')
      ;
    int index=i;
    p=new char[myString.length()-i];
    while(i<myString.length()){
      p[i-index]=reccord[i];
      i++;
    }
    // System.out.println("\nTransport= "+trans+"\nport="+p);
    String myport=new String(p);
    // System.out.println("\nmyport:"+myport);
    return TH=new TransportHeader(trans.toString(),Integer.parseInt(myport));
  }

  public GeneralHeader getGeneralHeader(){
    return this.generalheader;
  }

  public ResponseHeader getResponseHeader(){
    return this.responseheader;
  }
  public int isGeneralHeader(GeneralHeader genhea,String msg,int beginindex){
    int endindex=beginindex;

    if(msg.startsWith("Cache-Control:",beginindex)){
      beginindex=msg.indexOf("Cache-Control:",beginindex)+"Cache-Control:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	genhea.setCacheControl(msg.substring(beginindex+1));
      else
	genhea.setCacheControl(msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    if(msg.startsWith("Connection:",endindex)){
      beginindex=msg.indexOf("Connection:",endindex)+"Connection:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	genhea.setConnection(msg.substring(beginindex+1));
      else
	genhea.setConnection(msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    if(msg.startsWith("Date:",endindex)){
      beginindex=msg.indexOf("Date:",endindex)+"Date:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	genhea.setDate(new RtspDate(msg.substring(beginindex+1,endindex)));
      else
	genhea.setDate(new RtspDate(msg.substring(beginindex+1)));
      // System.out.println("\nDATE OBJECT :"+genhea.getDate().toString());
      endindex+=2;
    }
    if(msg.startsWith("Via",endindex)){
      beginindex=msg.indexOf("Via",endindex)+"Via".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	genhea.setVia(msg.substring(beginindex+1,endindex));
      else
	genhea.setVia(msg.substring(beginindex+1));
      endindex+=2;
    }
    return endindex;
  }
 public int isResponseHeader(ResponseHeader rephea,String msg,int beginindex){
   int endindex=beginindex;

   if(msg.startsWith("Location:",beginindex)){
     beginindex=msg.indexOf("Location:",endindex)+"Location:".length();
     endindex=msg.indexOf("\r\n",beginindex);
   if(endindex!=-1)
     rephea.setLocation(msg.substring(beginindex+1,endindex));
   else
     rephea.setLocation(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("Proxy-Authenticate:",endindex)){
     beginindex=msg.indexOf("Proxy-Authenticate:",endindex)+"Proxy-Authenticate:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       rephea.setProxyAuthenticate(msg.substring(beginindex+1,endindex)); 
     else
       rephea.setProxyAuthenticate(msg.substring(beginindex+1)); 
     endindex+=2;
   }
    if(msg.startsWith("Public:",endindex)){
     beginindex=msg.indexOf("Public:",endindex)+"Public:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       rephea.setPublic(msg.substring(beginindex+1,endindex));
     else
       rephea.setPublic(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("Retry-After:",beginindex)){
     beginindex=msg.indexOf("Retry-After:",endindex)+"Retry-After:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       rephea.setRetryAfter(msg.substring(beginindex+1,endindex));
     else
       rephea.setRetryAfter(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("Server:",endindex)){
     beginindex=msg.indexOf("Server:",endindex)+"Server:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       rephea.setServer(msg.substring(beginindex+1,endindex));
     else
       rephea.setServer(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("Vary:",endindex)){
     beginindex=msg.indexOf("Vary:",endindex)+"Vary:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       rephea.setVary(msg.substring(beginindex+1,endindex));
     else
       rephea.setVary(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("WWW-Authenticate:",endindex)){
      beginindex=msg.indexOf("WWW-Authenticate:",endindex)+"WWW-Authenticate:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	rephea.setWWWAuthenticate(msg.substring(beginindex+1,endindex));
      else
	rephea.setWWWAuthenticate(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Range:",endindex)){
      beginindex=msg.indexOf("Range:",endindex)+"Range:".length();
      endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       rephea.setRange(msg.substring(beginindex+1,endindex));
       else
	 rephea.setRange(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Scale:",endindex)){
      beginindex=msg.indexOf("Scale:",endindex)+"Scale:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	rephea.setScale(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      else
	rephea.setScale(Integer.parseInt(msg.substring(beginindex+1)));
      endindex+=2;
    }
    if(msg.startsWith("Session:",endindex)){
      beginindex=msg.indexOf("Session:",endindex)+"Session:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	rephea.setSession(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      else
	rephea.setSession(Integer.parseInt(msg.substring(beginindex+1)));
      //  System.out.println("\nSESSION : "+rephea.getSession());
      endindex+=2;
    }
    if(msg.startsWith("Speed:",endindex)){
      beginindex=msg.indexOf("Speed:",endindex)+"Speed:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	rephea.setSpeed(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      else
	rephea.setSpeed(Integer.parseInt(msg.substring(beginindex+1)));
      endindex+=2;
    }
    return endindex;
 }
  
  //test if the str is reccord of the Entity header.
   
  public int isEntityHeader(EntityHeader enthea,String msg,int beginindex){
    int endindex=beginindex;
    if(msg.startsWith("Allow:",beginindex)){
      beginindex=msg.indexOf("Allow:",beginindex)+"Allow:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	enthea.setAllow(msg.substring(beginindex+1,endindex));
      else
	enthea.setAllow(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Content-Encoding:",endindex)){
      // System.out.println("\nmessage contentEncoding :"+msg.substring(endindex));
      beginindex=msg.indexOf("Content-Encoding:",endindex)+"Content-Encoding:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	enthea.setContentEncoding(msg.substring(beginindex+1,endindex));
      else
	enthea.setContentEncoding(msg.substring(beginindex+1));
      // System.out.println("\ncontentEncoding:"+msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    if(msg.startsWith("Content-Language:",endindex)){
      beginindex=msg.indexOf("Content-Language:",endindex)+"Content-Language:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	enthea.setContentLanguage(msg.substring(beginindex+1,endindex));
     else
       enthea.setContentLanguage(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Content-Length:",endindex)){
      beginindex=msg.indexOf("Content-Length:",endindex)+"Content-Length:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setContentLength(Integer.parseInt(msg.substring(beginindex+1)));
      else
	enthea.setContentLength(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      endindex+=2;
    }
    if(msg.startsWith("Content-Type:",endindex)){
      beginindex=msg.indexOf("Content-Type:",endindex)+"Content-Type:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setContentType(msg.substring(beginindex+1,endindex));
      else
	enthea.setContentType(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Expires:",endindex)){
      beginindex=msg.indexOf("Expires:",endindex)+"Expires:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setExpires(msg.substring(beginindex+1,endindex));
      else
	enthea.setExpires(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Last-Modified:",endindex)){
      beginindex=msg.indexOf("Last-Modified:",endindex)+"Last-Modified:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setLastModified(msg.substring(beginindex+1,endindex));
      else
	enthea.setLastModified(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Extension-Header:",endindex)){
      beginindex=msg.indexOf("Extension-Header:",endindex)+"Extension-Header:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setExtensionHeader(msg.substring(beginindex+1,endindex));
      else
	enthea.setExtensionHeader(msg.substring(beginindex+1));
      endindex+=2;
    }
    return endindex;
  }

  public int isTransportHeader(TransportHeader trahea,String msg,int beginindex){
    int endindex=beginindex;
    TransportHeader tmp=new TransportHeader();
    if(msg.startsWith("Transport:",beginindex)){
      beginindex=msg.indexOf("Transport:",beginindex)+"Transport:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      // System.out.println("\nDEBUT INDEX TRANSPORT:"+beginindex);
      // System.out.println("\nEND INDEX TRANSPORT:"+endindex);
      // System.out.println("\nTRANSPORT :"+msg.substring(beginindex+1));//,endindex));
      if(endindex==-1){
	tmp=parseTransportHeader(msg.substring(beginindex+1));
	//System.out.println("\nTRANSPORT trans:"+tmp.getTransport());
	trahea.setTransport(tmp.getTransport());
	trahea.setPort(tmp.getPort());
	//	System.out.println("\nAVANT:"+trahea.getPort());
      }
      else
	trahea=parseTransportHeader(msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    return endindex;
  }

  public String getBodyMessage(){
    return BodyMessage;
  }

}

