/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package local.ua;

import mdot.Main;
import org.zoolu.sip.address.*;
import org.zoolu.sip.provider.*;
import org.zoolu.net.SocketAddress;
import org.zoolu.tools.Log;
import org.zoolu.tools.LogLevel;


/**
 *
 * @author student
 */
public class UACallSetup implements UserAgentListener, RegisterAgentListener{

    /**
     * @return the call_status
     */
    public static String getCallStatus() {
        return call_status;
    }



   /** Event logger. */
   Log log;

   /** User Agent */
   UserAgent ua;

   /** Register Agent */
   RegisterAgent ra;

   /** UserAgentProfile */
   private  static UserAgentProfile user_profile;

   /**SipProvider*/
    private static SipProvider sip_provider;
 

   /** Recent contacts */
   protected static final int NMAX_CONTACTS=10;

   /** Recent contacts */
   StringList contact_list;

   /**Call Status **/
   private static String call_status = "";

   public UACallSetup()
   {
        Setup();

      log=sip_provider.getLog();
      this.user_profile=user_profile;

      ua=new UserAgent(sip_provider,user_profile,this);
      ua.listen();
      ra=new RegisterAgent(sip_provider,user_profile.from_url,user_profile.contact_url,user_profile.username,user_profile.realm,user_profile.passwd,this);

     
      contact_list=new StringList(user_profile.contacts_file);
      
      run();
   
   }

    
   void run()
   {
      // Set the re-invite
      if (user_profile.re_invite_time>0)
      {  ua.reInvite(user_profile.contact_url,user_profile.re_invite_time);
      }

      // Set the transfer (REFER)
      if (user_profile.transfer_to!=null && user_profile.transfer_time>0)
      {  ua.callTransfer(user_profile.transfer_to,user_profile.transfer_time);
      }

      if (user_profile.do_unregister_all)
      // ########## unregisters ALL contact URLs
      {  ua.printLog("UNREGISTER ALL contact URLs");
         unregisterall();
      }

      if (user_profile.do_unregister)
      // unregisters the contact URL
      {  ua.printLog("UNREGISTER the contact URL");
         unregister();
      }

      if (user_profile.do_register)
      // ########## registers the contact URL with the registrar server
      {  ua.printLog("REGISTRATION");
         loopRegister(user_profile.expires,user_profile.expires/2,user_profile.keepalive_time);
      }

      if (user_profile.call_to!=null)
      // ########## make a call with the remote URL
      {  ua.printLog("UAC: CALLING "+user_profile.call_to);
        
         ua.call(user_profile.call_to);
      }

      if (!user_profile.audio && !user_profile.video) ua.printLog("ONLY SIGNALING, NO MEDIA");
   }

    /** Register with the registrar server
     * @param expire_time expiration time in seconds */
   public void register(int expire_time)
   {  if (ra.isRegistering()) ra.halt();
      ra.register(expire_time);
   }


   /** Periodically registers the contact address with the registrar server.
     * @param expire_time expiration time in seconds
     * @param renew_time renew time in seconds
     * @param keepalive_time keep-alive packet rate (inter-arrival time) in milliseconds */
   public void loopRegister(int expire_time, int renew_time, long keepalive_time)
   {  if (ra.isRegistering()) ra.halt();
      ra.loopRegister(expire_time,renew_time,keepalive_time);
   }


   /** Unregister with the registrar server */
   public void unregister()
   {  if (ra.isRegistering()) ra.halt();
      ra.unregister();
   }


   /** Unregister all contacts with the registrar server */
   public void unregisterall()
   {  if (ra.isRegistering()) ra.halt();
      ra.unregisterall();
   }


   // ********************** UA callback functions **********************


   /** When a new call is incoming */
   public void onUaCallIncoming(UserAgent ua, NameAddress callee, NameAddress caller)
   {
      if (ua.user_profile.redirect_to!=null) // redirect the call
      { 
         ua.redirect(ua.user_profile.redirect_to);
      }
      else
      if (ua.user_profile.accept_time>=0) // automatically accept the call
      {  
         
         ua.automaticAccept(ua.user_profile.accept_time);
      }
      else
      {  
      }
   }

   /** When an ougoing call is remotly ringing */
   public void onUaCallRinging(UserAgent ua)
   {
     call_status = "Ringing....";
   }

   /** When an ougoing call has been accepted */
   public void onUaCallAccepted(UserAgent ua)
   {
        call_status = "Connection established.";
   }


   /** When an incoming call has been cancelled */
   public void onUaCallCancelled(UserAgent ua)
   {
      call_status = "Call canceled.";
      ua.listen();
   }


   /** When a call has been trasferred */
   public void onUaCallTrasferred(UserAgent ua)
   {
     
      ua.listen();
   }

   /** When an ougoing call has been refused or timeout */
   public void onUaCallFailed(UserAgent ua)
   {
     call_status = "Call could not be completed.";
      ua.listen();
   }

   /** When a call has been locally or remotely closed */
   public void onUaCallClosed(UserAgent ua)
   {
      call_status = "Call ended.";
      ua.listen();
   }


   // ********************** RA callback functions **********************

   /** When a UA has been successfully (un)registered. */
   public void onUaRegistrationSuccess(RegisterAgent ra, NameAddress target, NameAddress contact, String result)
   {  ua.printLog("Registration success: "+result,LogLevel.HIGH);
      
   }

   /** When a UA failed on (un)registering. */
   public void onUaRegistrationFailure(RegisterAgent ra, NameAddress target, NameAddress contact, String result)
   {  ua.printLog("Registration failure: "+result,LogLevel.HIGH);
      
   }

    //Read data from config file
    public static void Setup()
    {

      String file=Main.voipCFG;

      boolean opt_regist=false;
      boolean opt_unregist=false;
      boolean opt_unregist_all=false;
      int     opt_expires=-1;
      long    opt_keepalive_time=-1;
      boolean opt_no_offer=false;
      String  opt_call_to=null;
      int     opt_accept_time=-1;
      int     opt_hangup_time=-1;
      String  opt_redirect_to=null;
      String  opt_transfer_to=null;
      int     opt_transfer_time=-1;
      int     opt_re_invite_time=-1;
      boolean opt_audio=false;
      boolean opt_video=false;
      int     opt_media_port=0;
      boolean opt_recv_only=false;
      boolean opt_send_only=false;
      boolean opt_send_tone=false;
      String  opt_send_file=null;
      String  opt_recv_file=null;
      boolean opt_no_prompt=false;

      String opt_from_url=null;
      String opt_contact_url=null;
      String opt_username=null;
      String opt_realm=null;
      String opt_passwd=null;

      int opt_debug_level=-1;
      String opt_log_path=null;
      String opt_outbound_proxy=null;
      String opt_via_addr=SipProvider.AUTO_CONFIGURATION;
      int opt_host_port=SipStack.default_port;

    
          SipStack.init(file);
         if (opt_debug_level>=0) SipStack.debug_level=opt_debug_level;
         if (opt_log_path!=null) SipStack.log_path=opt_log_path;
        
         if (file!=null) sip_provider=new SipProvider(file); else sip_provider=new SipProvider(opt_via_addr,opt_host_port);
         if (opt_outbound_proxy!=null) sip_provider.setOutboundProxy(new SocketAddress(opt_outbound_proxy));
       
          user_profile=new UserAgentProfile(file);



         if (opt_regist) user_profile.do_register=true;
         if (opt_unregist) user_profile.do_unregister=true;
         if (opt_unregist_all) user_profile.do_unregister_all=true;
         if (opt_expires>0) user_profile.expires=opt_expires;
         if (opt_keepalive_time>=0) user_profile.keepalive_time=opt_keepalive_time;
         if (opt_hangup_time>0) user_profile.hangup_time=opt_hangup_time;
         if (opt_no_offer) user_profile.no_offer=true;
         if (opt_call_to!=null) user_profile.call_to=opt_call_to;
         if (opt_accept_time>=0) user_profile.accept_time=opt_accept_time;
         if (opt_redirect_to!=null) user_profile.redirect_to=opt_redirect_to;
         if (opt_re_invite_time>0) user_profile.re_invite_time=opt_re_invite_time;
         if (opt_transfer_to!=null) user_profile.transfer_to=opt_transfer_to;
         if (opt_transfer_time>0) user_profile.transfer_time=opt_transfer_time;
         if (opt_audio) user_profile.audio=true;
         if (opt_video) user_profile.video=true;
         if (opt_media_port>0) user_profile.video_port=(user_profile.audio_port=opt_media_port)+2;
         if (opt_from_url!=null) user_profile.from_url=opt_from_url;
         if (opt_contact_url!=null) user_profile.contact_url=opt_contact_url;
         if (opt_username!=null) user_profile.username=opt_username;
         if (opt_realm!=null) user_profile.realm=opt_realm;
         if (opt_passwd!=null) user_profile.passwd=opt_passwd;
         if (opt_recv_only) user_profile.recv_only=true;
         if (opt_send_only) user_profile.send_only=true;
         if (opt_send_tone) user_profile.send_tone=true;
         if (opt_send_file!=null) user_profile.send_file=opt_send_file;
         if (opt_recv_file!=null) user_profile.recv_file=opt_recv_file;
         if (opt_no_prompt) user_profile.no_prompt=true;

         // use audio as default media in case of..
         if ((opt_recv_only || opt_send_only || opt_send_tone || opt_send_file!=null || opt_recv_file!=null) && !opt_video) user_profile.audio=true;

        

   }

   public void makeCall()
   {
     if (ua.statusIs(UserAgent.UA_IDLE))
      {
         String url = Main.voipURL;
         //String url ="<sip:bob@192.168.1.69:5080>";
         //String url ="<sip:alice@10.1.1.3:5070>";
         
         if (url!=null && url.length()>0)
         {  ua.hangup();
            ua.call(url);
            System.out.println("CALLING "+url);
            call_status = "Calling " + url;
         }
      }
      else
      if (ua.statusIs(UserAgent.UA_INCOMING_CALL))
      {  ua.accept();
         call_status = "Incoming call accepted.";

      }


   }

   public void endCall()
   {
      if (!ua.statusIs(UserAgent.UA_IDLE))
      {  ua.hangup();
         ua.listen();

         call_status = "Call canceled.";
         System.out.println("ENDING THE CALL!");
        
      }
   }

   public void quit()
   {
      System.exit(0);
   }



}
