/*
* The SIP class encapsulates a SIP message contents and provides
* methods to construct, parse, send, and receive messages over the 
* TCP/IP connection.  It is used by both the user agent client 
* (the CallerDialog object) and the user agent server (UAServer).
* CallerDialog constructs a SIP object incorporating user input when 
* the caller clicks on the "call" button from the dialog box.
* UAServer also constructs a SIP object, but it does so by reading
* from the socket input stream. 
*
*
* Author: Janet H. Park
* Date: August, 1998
*
*/

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

public class SIP {
	
	String from;
	String to;
	String subject = "";
	String priority = "";
	String call_id;
	String cseq;
	String content_type;
	String content_length;

	String callID;
	String callerId;
	String callerAddr;
	String calleeId;
	String calleeAddr;

	final static String SIPVER = "SIP/2.0";

	public SIP (String callerId, String callerAddr, String calleeId, 
	           String calleeAddr, String subj, String prior, int sdp_length) {

		// construct a sip message set for the caller 

		this.callerId = callerId;
		this.calleeId = calleeId;
		this.callerAddr = callerAddr;
		this.calleeAddr = calleeAddr;

		from = "From: " + callerId + "@" + callerAddr;
		to = "To: " + calleeId + "@" + calleeAddr;
		if (!subj.equals(""))
			subject  = "Subject: " + subj;
		if (!prior.equals(""))
			priority  = "Priority: " + prior;
		content_type = "Content-Type: application/sdp";
		content_length = "Content-Length: " + sdp_length;
		int callID = Math.abs(new Random (System.currentTimeMillis()).nextInt());
		call_id = "Call-ID: " + String.valueOf(callID)+"@"+callerAddr;
		int seq = new Random().nextInt();
		cseq = "CSeq: " + String.valueOf(seq);

	}



	public SIP (BufferedReader in, CalleeDialog win, UAServer svr ) 
	{

	// constructed by the callee by reading the sip messages 
	// from the given input stream
	//
	  try {
		String line = "";
		while ((line = in.readLine()) != null) {
			svr.log("RECV> " + line);
			if (line.length() == 0)
				break;

			StringTokenizer st = new StringTokenizer(line);
			String tok = st.nextToken();

			if (tok.equals("From:")) {
				from = line;
				win.setCallerId(st.nextToken("@"));
				win.setCallerAddr(st.nextToken());
			}
			else if (tok.equals("To:")) {
				to = line;
				calleeId = st.nextToken("@").trim();
				win.setCalleeId(calleeId);
				String calleeHost = st.nextToken();
				win.setCalleeAddr(calleeHost);
				calleeAddr = InetAddress.getByName(calleeHost).getHostAddress();
			}
			else if (tok.equals("Subject:")) {
				subject = line;
				StringBuffer buf = new StringBuffer();
				while (st.hasMoreTokens())
					buf = buf.append(st.nextToken()).append(" ");
				win.setSubject(buf.toString());
			}
			else if (tok.equals("Priority:")) { 
				priority = line;
				win.setPriority(st.nextToken());
			}
			else if (tok.equals("Call-ID:")) {
				
				call_id = line;
				callID = st.nextToken();
			}
			else if (tok.equals("CSeq:"))
				cseq = line;
			else if (tok.equals("Content-Type:"))
				content_type = line;
			else if (tok.equals("Content_Length:")) 
				content_length = line;
		}
	  } catch(IOException e) {
		svr.log("IOException occured" );
		System.out.println("SIP.SIP():"+e);
	  }
		
	}



	void sendInvite(PrintWriter out, CallerDialog win) 
	{
		String invite = "INVITE " + calleeId  + "@" + calleeAddr + " " +SIPVER;
		out.println(invite);
		win.log("SEND> " + invite);
		out.println(from);
		win.log("SEND> " +from);
		out.println(to);
		win.log("SEND> " + to);
		if (!subject.equals("")) {
			out.println(subject);
			win.log("SEND> " + subject);
		}
		if (!priority.equals("")) {
			out.println(priority);
			win.log("SEND> " + priority);
		}
		out.println(call_id);
		win.log("SEND> " + call_id);
		out.println(cseq);
		win.log("SEND> " + cseq);
		out.println(content_type);
		win.log("SEND> " + content_type);
		out.println(content_length);
		win.log("SEND> " + content_length);
		out.println("");
		win.log("SEND>");
	}


	void sendReq(String req, PrintWriter out, CallerDialog win) 
	{
		String request = req + " " + calleeId  + "@" + calleeAddr + " " +SIPVER;
		out.println(request);
		win.log("SEND> " + request);
		out.println(from);
		win.log("SEND> " +from);
		out.println(to);
		win.log("SEND> " + to);
		out.println(call_id);
		win.log("SEND> " + call_id);
		out.println(cseq);
		win.log("SEND> " + cseq);
		out.println("");
		win.log("SEND>");
	}


	void readRequest(BufferedReader in, CalleeDialog win, UAServer svr) 
	{
	  try {
		String line;
		while ((line = in.readLine()) != null) {
			svr.log("RECV> " + line);
			if (line.length() == 0)
				break;

			StringTokenizer st = new StringTokenizer(line);
			String tok = st.nextToken();

			if (tok.equals("From:")) 
				from = line;
			else if (tok.equals("To:")) 
				to = line;
			else if (tok.equals("Subject:")) 
				subject = line;
			else if (tok.equals("Priority:")) 
				priority = line;
			else if (tok.equals("Call-ID:")) 
				call_id = line;
			else if (tok.equals("CSeq:")) 
				cseq = line;
			else if (tok.equals("Content-Type:")) 
				content_type = line;
			else if (tok.equals("Content_Length:"))
				content_length = line;
		}
	  } catch(IOException e) {
		svr.log("IOException occured" );
		System.out.println("SIP.readRequest():"+e);
	  }
	}


	void sendResp(String resp, PrintWriter out, CalleeDialog win, UAServer svr) {
		out.println(SIPVER + " " + resp);
		svr.log("SEND> " + SIPVER +" " + resp);
		out.println(from);
		svr.log("SEND> " + from);
		out.println(to);
		svr.log("SEND> " + to);
		out.println(call_id);
		svr.log("SEND> " + call_id);
		out.println(cseq);
		svr.log("SEND> " + cseq);
		out.println("");
		svr.log("SEND> ");
	}

	void sendMoved(String resp, String addr, PrintWriter out, CalleeDialog win, UAServer svr) {
		out.println(SIPVER + " " + resp);
		svr.log("SEND> " + SIPVER +" " + resp);
		out.println(from);
		svr.log("SEND> " + from);
		out.println(to);
		svr.log("SEND> " + to);
		out.println(call_id);
		svr.log("SEND> " + call_id);

		String loc = "Location: sip:@" + addr;
		out.println(loc);
		svr.log("SEND> " + loc);

		out.println(cseq);
		svr.log("SEND> " + cseq);
		out.println("");
		svr.log("SEND> ");
	}


	String getCalleeAddr() { return calleeAddr; }


	String getCalleeId() { return calleeId; }

	void setCalleeAddr(String addr) 
	{
		calleeAddr = addr ;
		to = "To: " + calleeId + "@" + calleeAddr;
		
	}


}
