* #29924: removed sliding incall panel
diff --git a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
index cb6cb0b..1072562 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
@@ -37,24 +37,35 @@
 
 import android.app.Activity;
 import android.app.Fragment;
+import android.content.ClipData;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ClipData.Item;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.Vibrator;
 import android.util.Log;
+import android.view.DragEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.View.DragShadowBuilder;
+import android.view.View.OnDragListener;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.BaseAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.fragments.CallListFragment.DropActionsChoice;
 import com.savoirfairelinux.sflphone.model.CallTimer;
 import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
@@ -64,11 +75,12 @@
     private static final String TAG = HomeFragment.class.getSimpleName();
 
     private Callbacks mCallbacks = sDummyCallbacks;
-    TextView nb_calls, nb_confs;
-    CallListAdapter confs_adapter;
+    private TextView nb_calls, nb_confs;
+    CallListAdapter confs_adapter, calls_adapter;
     CallTimer timer;
-
-    private CallListAdapter calls_adapter;
+    
+    public static final int REQUEST_TRANSFER = 10;
+    public static final int REQUEST_CONF = 20;
 
     /**
      * A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
@@ -133,7 +145,7 @@
             try {
                 updateLists();
                 if (!calls_adapter.isEmpty() || !confs_adapter.isEmpty()) {
-                    mHandler.postDelayed(mUpdateTimeTask, 0);                
+                    mHandler.postDelayed(mUpdateTimeTask, 0);
                 }
 
             } catch (RemoteException e) {
@@ -143,7 +155,8 @@
 
     }
 
-    @SuppressWarnings("unchecked") // No proper solution with HashMap runtime cast
+    @SuppressWarnings("unchecked")
+    // No proper solution with HashMap runtime cast
     public void updateLists() throws RemoteException {
         HashMap<String, SipCall> calls = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
         HashMap<String, Conference> confs = (HashMap<String, Conference>) mCallbacks.getService().getConferenceList();
@@ -183,9 +196,9 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
     }
-    
+
     @Override
-    public void onPause(){
+    public void onPause() {
         super.onPause();
         mHandler.removeCallbacks(mUpdateTimeTask);
     }
@@ -227,6 +240,9 @@
         ((ListView) inflatedView.findViewById(R.id.calls_list)).setOnItemClickListener(callClickListener);
         ((ListView) inflatedView.findViewById(R.id.confs_list)).setOnItemClickListener(callClickListener);
 
+        ((ListView) inflatedView.findViewById(R.id.calls_list)).setOnItemLongClickListener(mItemLongClickListener);
+        ((ListView) inflatedView.findViewById(R.id.confs_list)).setOnItemLongClickListener(mItemLongClickListener);
+
         return inflatedView;
     }
 
@@ -238,6 +254,25 @@
         }
     };
 
+    private OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() {
+
+        @Override
+        public boolean onItemLongClick(AdapterView<?> adptv, View view, int pos, long arg3) {
+            final Vibrator vibe = (Vibrator) view.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+            vibe.vibrate(80);
+            Intent i = new Intent();
+            Bundle b = new Bundle();
+            b.putParcelable("conference", (Conference) adptv.getAdapter().getItem(pos));
+            i.putExtra("bconference", b);
+
+            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
+            ClipData data = ClipData.newIntent("conference", i);
+            view.startDrag(data, shadowBuilder, view, 0);
+            return false;
+        }
+
+    };
+
     public class CallListAdapter extends BaseAdapter implements Observer {
 
         private ArrayList<Conference> calls;
@@ -291,7 +326,8 @@
 
                 long duration = System.currentTimeMillis() / 1000 - (call.getParticipants().get(0).getTimestamp_start());
 
-                ((TextView) convertView.findViewById(R.id.call_time)).setText(String.format("%d:%02d:%02d", duration/3600, (duration%3600)/60, (duration%60)));
+                ((TextView) convertView.findViewById(R.id.call_time)).setText(String.format("%d:%02d:%02d", duration / 3600, (duration % 3600) / 60,
+                        (duration % 60)));
             } else {
                 String tmp = "Conference with " + call.getParticipants().size() + " participants";
                 ((TextView) convertView.findViewById(R.id.call_title)).setText(tmp);
@@ -299,7 +335,9 @@
             // ((TextView) convertView.findViewById(R.id.num_participants)).setText("" + call.getParticipants().size());
             ((TextView) convertView.findViewById(R.id.call_status)).setText(call.getState());
 
+            convertView.setOnDragListener(dragListener);
             convertView.setTag(call);
+
             return convertView;
         }
 
@@ -311,4 +349,144 @@
 
     }
 
+    OnDragListener dragListener = new OnDragListener() {
+
+        @SuppressWarnings("deprecation")
+        // deprecated in API 16....
+        @Override
+        public boolean onDrag(View v, DragEvent event) {
+            switch (event.getAction()) {
+            case DragEvent.ACTION_DRAG_STARTED:
+                // Do nothing
+                Log.w(TAG, "ACTION_DRAG_STARTED");
+                break;
+            case DragEvent.ACTION_DRAG_ENTERED:
+                Log.w(TAG, "ACTION_DRAG_ENTERED");
+                v.setBackgroundColor(Color.GREEN);
+                break;
+            case DragEvent.ACTION_DRAG_EXITED:
+                Log.w(TAG, "ACTION_DRAG_EXITED");
+                v.setBackgroundDrawable(getResources().getDrawable(R.drawable.item_call_selector));
+                break;
+            case DragEvent.ACTION_DROP:
+                Log.w(TAG, "ACTION_DROP");
+                View view = (View) event.getLocalState();
+
+                Item i = event.getClipData().getItemAt(0);
+                Intent intent = i.getIntent();
+                intent.setExtrasClassLoader(Conference.class.getClassLoader());
+
+                Conference initial = (Conference) view.getTag();
+                Conference target = (Conference) v.getTag();
+
+                if (initial == target) {
+                    return true;
+                }
+
+                DropActionsChoice dialog = DropActionsChoice.newInstance();
+                Bundle b = new Bundle();
+                b.putParcelable("call_initial", initial);
+                b.putParcelable("call_targeted", target);
+                dialog.setArguments(b);
+                dialog.setTargetFragment(HomeFragment.this, 0);
+                dialog.show(getFragmentManager(), "dialog");
+
+                // view.setBackgroundColor(Color.WHITE);
+                // v.setBackgroundColor(Color.BLACK);
+                break;
+            case DragEvent.ACTION_DRAG_ENDED:
+                Log.w(TAG, "ACTION_DRAG_ENDED");
+                View view1 = (View) event.getLocalState();
+                view1.setVisibility(View.VISIBLE);
+                v.setBackgroundDrawable(getResources().getDrawable(R.drawable.item_call_selector));
+            default:
+                break;
+            }
+            return true;
+        }
+
+    };
+    
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        Conference transfer = null;
+        if (requestCode == REQUEST_TRANSFER) {
+            switch (resultCode) {
+            case 0:
+                Conference c = data.getParcelableExtra("target");
+                transfer = data.getParcelableExtra("transfer");
+                try {
+
+                    mCallbacks.getService().attendedTransfer(transfer.getParticipants().get(0).getCallId(), c.getParticipants().get(0).getCallId());
+                    calls_adapter.remove(transfer);
+                    calls_adapter.remove(c);
+                    calls_adapter.notifyDataSetChanged();
+                } catch (RemoteException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                Toast.makeText(getActivity(), "Transfer complete", Toast.LENGTH_LONG).show();
+                break;
+
+            case 1:
+                String to = data.getStringExtra("to_number");
+                transfer = data.getParcelableExtra("transfer");
+                try {
+                    Toast.makeText(getActivity(), "Transferring " + transfer.getParticipants().get(0).getContact().getmDisplayName() + " to " + to,
+                            Toast.LENGTH_SHORT).show();
+                    mCallbacks.getService().transfer(transfer.getParticipants().get(0).getCallId(), to);
+                    mCallbacks.getService().hangUp(transfer.getParticipants().get(0).getCallId());
+                } catch (RemoteException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                break;
+
+            default:
+                break;
+            }
+        } else if (requestCode == REQUEST_CONF) {
+            switch (resultCode) {
+            case 0:
+                Conference call_to_add = data.getParcelableExtra("transfer");
+                Conference call_target = data.getParcelableExtra("target");
+
+                bindCalls(call_to_add, call_target);
+                break;
+
+            default:
+                break;
+            }
+        }
+    }
+    
+    private void bindCalls(Conference call_to_add, Conference call_target) {
+        try {
+
+            if (call_target.hasMultipleParticipants() && !call_to_add.hasMultipleParticipants()) {
+
+                mCallbacks.getService().addParticipant(call_to_add.getParticipants().get(0), call_target.getId());
+
+            } else if (call_target.hasMultipleParticipants() && call_to_add.hasMultipleParticipants()) {
+
+                // We join two conferences
+                mCallbacks.getService().joinConference(call_to_add.getId(), call_target.getId());
+
+            } else if (!call_target.hasMultipleParticipants() && call_to_add.hasMultipleParticipants()) {
+
+                mCallbacks.getService().addParticipant(call_target.getParticipants().get(0), call_to_add.getId());
+
+            } else {
+                // We join two single calls to create a conf
+                mCallbacks.getService().joinParticipant(call_to_add.getParticipants().get(0).getCallId(),
+                        call_target.getParticipants().get(0).getCallId());
+            }
+
+        } catch (RemoteException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
 }