/*
 *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
 *
 *  Author: Alexandre Savard <alexandre.savard@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */
package com.savoirfairelinux.sflphone.client;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;

import com.savoirfairelinux.sflphone.service.ISipService;
import com.savoirfairelinux.sflphone.client.CallActivity;
import com.savoirfairelinux.sflphone.client.CallElementList.CallElementView;

public class SipCall
{
    final static String TAG = "SipCall";
    public CallInfo mCallInfo;
    // Update UI on actions (answer, hangup)
    static private CallElementList mCallElementList = null;
    static private SFLPhoneHome mHome = null;
    private View mRowView = null;

    public static final int CALL_TYPE_UNDETERMINED = 0;
    public static final int CALL_TYPE_INCOMING = 1;
    public static final int CALL_TYPE_OUTGOING = 2;

    public static final int CALL_STATE_NONE = 0;
    public static final int CALL_STATE_INCOMING = 1;
    public static final int CALL_STATE_RINGING = 2;
    public static final int CALL_STATE_CURRENT = 3;
    public static final int CALL_STATE_HUNGUP = 4;
    public static final int CALL_STATE_BUSY = 5;
    public static final int CALL_STATE_FAILURE = 6;
    public static final int CALL_STATE_HOLD = 7;
    public static final int CALL_STATE_UNHOLD = 8;

    public static final int MEDIA_STATE_NONE = 0;        // No media currently
    public static final int MEDIA_STATE_ACTIVE = 1;      // Media is active
    public static final int MEDIA_STATE_LOCAL_HOLD = 2;  // Media is put on hold bu user
    public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
    public static final int MEDIA_STATE_ERROR = 5;       // Media is in error state

    public static class CallInfo implements Parcelable
    {
        public String mCallID = "";
        public String mAccountID = "";
        public String mDisplayName = "";
        public String mPhone = "";
        public String mEmail = "";
        public String mRemoteContact = "";
        public int mCallType = CALL_TYPE_UNDETERMINED;
        public int mCallState = CALL_STATE_NONE;
        public int mMediaState = MEDIA_STATE_NONE;

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            ArrayList<String> list = new ArrayList<String>();

            // Don't mess with this order!!!
            list.add(mCallID);
            list.add(mAccountID);
            list.add(mDisplayName);
            list.add(mPhone);
            list.add(mEmail);
            list.add(mRemoteContact);

            out.writeStringList(list);
            out.writeInt(mCallType);
            out.writeInt(mCallState);
            out.writeInt(mMediaState);
        }

        public static final Parcelable.Creator<CallInfo> CREATOR
            = new Parcelable.Creator<CallInfo>() {
            public CallInfo createFromParcel(Parcel in) {
                return new CallInfo(in);
            }

            public CallInfo[] newArray(int size) {
                return new CallInfo[size];
            }
        };

        public CallInfo() {}

        private CallInfo(Parcel in) {
            ArrayList<String> list = in.createStringArrayList();

            // Don't mess with this order!!!
            mCallID = list.get(0);
            mAccountID = list.get(1);
            mDisplayName = list.get(2);
            mPhone = list.get(3);
            mEmail = list.get(4);
            mRemoteContact = list.get(5);

            mCallType = in.readInt();
            mCallState = in.readInt();
            mMediaState = in.readInt();
        }
    }

    public SipCall()
    {
        mCallInfo = new CallInfo(); 
    }

    public SipCall(CallInfo info)
    {
        mCallInfo = info; 
    }

    public static void setCallElementList(CallElementList list)
    {
        mCallElementList = list;
    }

    public static void setSFLPhoneHomeContext(SFLPhoneHome home)
    {
        mHome = home;
    }

    public void setAssociatedRowView(View view)
    {
        mRowView = view;
    }

    public void setCallID(String callID) {
        mCallInfo.mCallID = callID;
    }

    public String getCallId() {
        return mCallInfo.mCallID;
    }

    public void setAccountID(String accountID) {
        mCallInfo.mAccountID = accountID;
    }

    public String getAccountID() {
        return mCallInfo.mAccountID;
    }

    public void setDisplayName(String displayName) {
        mCallInfo.mDisplayName = displayName;
    }

    public String getDisplayName() {
        return mCallInfo.mDisplayName;
    }

    public void setPhone(String phone) {
        mCallInfo.mPhone = phone;
    }

    public String getPhone() {
        return mCallInfo.mPhone;
    }

    public void setEmail(String email) {
        mCallInfo.mEmail = email;
    }

    public String getEmail() {
        return mCallInfo.mEmail;
    }

    public void setRemoteContact(String remoteContact) {
        mCallInfo.mRemoteContact = remoteContact;
    }

    public String getRemoteContact() {
        return mCallInfo.mRemoteContact;
    }

    public void setCallType(int callType) {
        mCallInfo.mCallType = callType;
    }

    public int getCallType() {
        return mCallInfo.mCallType;
    }

    public void setCallState(int callState) {
        mCallInfo.mCallState = callState;
      
        // Check if this call is associated to a view in CallElementList 
        if(mRowView == null)
            return;

        // Update the state to the view
        CallElementView entryView = (CallElementView) mRowView.getTag();
        final String CURRENT_STATE_LABEL = "    CURRENT STATE: ";
        entryView.state.setText(CURRENT_STATE_LABEL + getCallStateString());
    }

    public int getCallStateInt() {
        return mCallInfo.mCallState;
    }

    public String getCallStateString() {
        String state;

        switch(mCallInfo.mCallState) {
            case CALL_STATE_INCOMING:
                state = "INCOMING";
                break;
            case CALL_STATE_RINGING:
                state = "RINGING";
                break;
            case CALL_STATE_CURRENT:
                state = "CURRENT";
                break;
            case CALL_STATE_HUNGUP:
                state = "HUNGUP";
                break;
            case CALL_STATE_BUSY:
                state = "BUSY";
                break;
            case CALL_STATE_FAILURE:
                state = "FAILURE";
                break;
            case CALL_STATE_HOLD:
                state = "HOLD";
                break;
            case CALL_STATE_UNHOLD:
                state = "UNHOLD";
                break;
            default:
                state = "NULL";
        }

        return state;
    }


    public void setMediaState(int mediaState) {
        mCallInfo.mMediaState = mediaState;
    }

    public int getMediaState() {
        return mCallInfo.mMediaState;
    }

    public void placeCallUpdateUi()
    {
        if(mCallElementList != null)
            mCallElementList.addCall(this);

        if(mHome != null)
            mHome.onSelectedCallAction(this);
    }

    public void notifyServicePlaceCall(ISipService service)
    {
        try {
            service.placeCall(mCallInfo.mAccountID, mCallInfo.mCallID, mCallInfo.mPhone);
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot call service method", e);
        }
    }

    public void receiveCallUpdateUi()
    {
        if(mCallElementList != null)
            mCallElementList.addCall(this); 

        if(mHome != null)
            mHome.onSelectedCallAction(this);
    }

    public void answerUpdateUi()
    {
        if(mHome != null)
            mHome.onSelectedCallAction(this);
        
    }

    public boolean notifyServiceAnswer(ISipService service)
    {
        int callState = getCallStateInt();
        if((callState != CALL_STATE_RINGING) &&
           (callState != CALL_STATE_NONE)) {
            return false;
        }

        try {
            service.accept(mCallInfo.mCallID);
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot call service method", e);
        }

        return true;
    }

    /**
     * Perform hangup action without sending request to the service
     * Used when SipService haved been notified that this call hung up
     */
    public void hangupUpdateUi() {
        Log.i(TAG, "Hangup call " + mCallInfo.mCallID);

        if(mCallElementList != null)
            mCallElementList.removeCall(this);

        if(mHome != null)
            mHome.onUnselectedCallAction();
    }

    /**
     * Perform hangup action and send request to the service
     */
    public boolean notifyServiceHangup(ISipService service)
    {
        try {
            if((getCallStateInt() == CALL_STATE_NONE) ||
               (getCallStateInt() == CALL_STATE_CURRENT) ||
               (getCallStateInt() == CALL_STATE_HOLD)) {
                service.hangUp(mCallInfo.mCallID);
                return true;

            }
            else if(getCallStateInt() == CALL_STATE_RINGING) {
                if(getCallType() == CALL_TYPE_INCOMING) {
                    service.refuse(mCallInfo.mCallID);
                    return true;
                }
                else if(getCallType() == CALL_TYPE_OUTGOING) {
                    service.hangUp(mCallInfo.mCallID);
                    return true;
                }
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot call service method", e);
        }

        return false;
    }

    public boolean notifyServiceRefuse(ISipService service)
    {
        try {
            if(getCallStateInt() == CALL_STATE_RINGING) {
                service.refuse(mCallInfo.mCallID);
                return true;
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot call service method", e);
        }

        return false;
    }

    public boolean notifyServiceHold(ISipService service)
    {
        try {
            if(getCallStateInt() == CALL_STATE_CURRENT) {
                service.hold(mCallInfo.mCallID);
                return true;
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot call service method", e);
        }

        return false;
    }

    public boolean notifyServiceUnhold(ISipService service)
    {
        try {
            if(getCallStateInt() == CALL_STATE_HOLD) {
                service.unhold(mCallInfo.mCallID);
                return true;
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot call service method", e);
        }

        return false;
    }

    public void addToConference()
    {
        Log.i(TAG, "Add call to conference");
    }

    public void sendTextMessage()
    {
        Log.i(TAG, "Send text message");
    }

    public void printCallInfo()
    {
        Log.i(TAG, "CallInfo: CallID: " + mCallInfo.mCallID);
        Log.i(TAG, "          AccountID: " + mCallInfo.mAccountID);
        Log.i(TAG, "          Display Name: " + mCallInfo.mDisplayName);
        Log.i(TAG, "          Phone: " + mCallInfo.mPhone);
        Log.i(TAG, "          Email: " + mCallInfo.mEmail);
        Log.i(TAG, "          Contact: " + mCallInfo.mRemoteContact);
    }

    public void launchCallActivity(Context context)
    {
        Log.i(TAG, "Launch Call Activity");
        Bundle bundle = new Bundle();
        bundle.putParcelable("CallInfo", mCallInfo);
        Intent intent = new Intent().setClass(context, CallActivity.class);
        intent.putExtras(bundle);
        context.startActivity(intent);
    }
}
