/*
 *  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.os.Parcelable;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;

import com.savoirfairelinux.sflphone.service.ISipService;

public class SipCall
{
    final static String TAG = "SipCall";
    public static CallElementList mCallElementList = null;
    public CallInfo mCallInfo;

    public static int CALL_STATE_INVALID = 0;      // The call is not existent in SFLphone service
    public static int CALL_STATE_NULL = 1;         // Before any action performed
    public static int CALL_STATE_CALLING = 2;      // After INVITE is sent
    public static int CALL_STATE_INCOMING = 3;     // After INVITE is received
    public static int CALL_STATE_EARLY = 4;        // After response with To tag
    public static int CALL_STATE_CONNECTING = 5;   // After 2xx is sent/received
    public static int CALL_STATE_CONFIRMED = 6;    // After ACK is sent/received
    public static int CALL_STATE_DISCONNECTED = 7; // Session is terminated

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

    public static class CallInfo implements Parcelable
    {
        public String mCallID = "";
        public String mDisplayName = "";
        public String mPhone = "";
        public String mEmail = "";
        public String mRemoteContact = "";
        public int mCallState = CALL_STATE_NULL;
        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(mDisplayName);
            list.add(mPhone);
            list.add(mEmail);
            list.add(mRemoteContact);

            out.writeStringList(list);
            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);
            mDisplayName = list.get(1);
            mPhone = list.get(2);
            mEmail = list.get(3);
            mRemoteContact = list.get(4);

            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 void placeCall()
    {
        if(mCallElementList != null)
            mCallElementList.addCall(this); 
        // mManager.callmanagerJNI.placeCall("IP2IP", "CALL1234", "192.168.40.35");
    }

    public void answer()
    {

    }

    public void hangup(ISipService service)
    {
        Log.i(TAG, "Hangup call " + mCallInfo.mCallID);

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

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

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

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