From 083b3ae6b03ab0d19f31ba4319857350a2390898 Mon Sep 17 00:00:00 2001
From: Nicolas Jager <nicolas.jager@savoirfairelinux.com>
Date: Tue, 4 Oct 2016 08:46:19 -0400
Subject: [PATCH] patch pour amelioration des etats

Change-Id: I5fd57088cc6a687edbaf80d556d275b7ea1040a7
Tuleap: #1205
---
 CallsViewModel.cpp              |  50 +-------------
 CallsViewModel.h                |  15 ++---
 Globals.h                       |   6 ++
 MainPage.xaml.cpp               |  15 ++---
 MainPage.xaml.h                 |   2 +-
 RingConsolePanel.xaml.cpp       |   2 +-
 RingD.cpp                       |  76 ++++++---------------
 RingD.h                         |  33 +++++----
 SmartPanel.xaml                 |  73 ++------------------
 SmartPanel.xaml.cpp             | 114 +++++++++++++-------------------
 SmartPanelItem.cpp              |  12 +++-
 SmartPanelItem.h                |  26 ++++++--
 SmartPanelItemsViewModel.cpp    |   8 +--
 SmartPanelItemsViewModel.h      |   5 +-
 VideoPage.xaml.cpp              |  11 +--
 pch.h                           |   4 +-
 ring-client-uwp.vcxproj         |   5 +-
 ring-client-uwp.vcxproj.filters |  15 +----
 18 files changed, 157 insertions(+), 315 deletions(-)
 create mode 100644 Globals.h

diff --git a/CallsViewModel.cpp b/CallsViewModel.cpp
index 07e9019..1bdb5a8 100644
--- a/CallsViewModel.cpp
+++ b/CallsViewModel.cpp
@@ -27,58 +27,12 @@ using namespace Windows::ApplicationModel::Core;
 
 CallsViewModel::CallsViewModel()
 {
-    CallsList_ = ref new Vector<Call^>();
+    callIdsList_ = ref new Vector<String^>();
 
     /* connect to delegates. */
 
     RingD::instance->incomingCall += ref new RingClientUWP::IncomingCall([&](
     String^ accountId, String^ callId, String^ from) {
-        auto call = addNewCall(accountId, callId, from);
-        if (call)
-            callRecieved(call);
+        callIdsList_->Append(callId); // TODO : check if the string is remove when the call ends.
     });
-    RingD::instance->stateChange += ref new RingClientUWP::StateChange(this, &RingClientUWP::ViewModel::CallsViewModel::OnstateChange);
-}
-
-Call^
-RingClientUWP::ViewModel::CallsViewModel::addNewCall(String^ accountId, String^ callId, String^ peer)
-{
-    if (accountId == "" | callId == "" | peer == "") {
-        WNG_("call can't be created");
-    }
-    auto call = ref new Call(accountId, callId, peer);
-    CallsList_->Append(call);
-    return call;
-}
-
-void RingClientUWP::ViewModel::CallsViewModel::clearCallsList()
-{
-    CallsList_->Clear();
-}
-
-Call^
-CallsViewModel::findCall(String^ callId)
-{
-    for each (Call^ call in CallsList_)
-        if (call->callId == callId)
-            return call;
-
-    return nullptr;
-}
-
-
-void RingClientUWP::ViewModel::CallsViewModel::OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code)
-{
-    auto call = findCall(callId);
-
-    if (!call)
-        return;
-
-    switch (state)
-    {
-    case CallStatus::ENDED:
-        RingD::instance->hangUpCall(call);
-    default:
-        break;
-    }
 }
diff --git a/CallsViewModel.h b/CallsViewModel.h
index 21c68ff..28e0864 100644
--- a/CallsViewModel.h
+++ b/CallsViewModel.h
@@ -41,18 +41,12 @@ internal:
         }
     }
 
-    /* functions */
-    Call^ addNewCall(String^ accountId, String^ callId, String^ from);
-    void clearCallsList();
-    //void setState(String^ callId, String^ state, int code); // used ?
-    Call^ findCall(String^ callId);
-
     /* properties */
-    property Vector<Call^>^ CallsList
+    property Vector<String^>^ _callIdList
     {
-        Vector<Call^>^ get()
+        Vector<String^>^ get()
         {
-            return CallsList_;
+            return callIdsList_;
         }
     }
 
@@ -64,9 +58,8 @@ internal:
 
 private:
     CallsViewModel(); // singleton
-    Vector<Call^>^ CallsList_; // refacto : change C to c
+    Vector<String^>^ callIdsList_;
 
-    void OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code);
 };
 }
 }
diff --git a/Globals.h b/Globals.h
new file mode 100644
index 0000000..1f4755b
--- /dev/null
+++ b/Globals.h
@@ -0,0 +1,6 @@
+namespace RingClientUWP
+{
+/* public enumerations. */
+public enum class CallStatus { NONE, INCOMING_RINGING, OUTGOING_RINGING, SEARCHING, IN_PROGRESS, ENDED, TERMINATING };
+
+}
\ No newline at end of file
diff --git a/MainPage.xaml.cpp b/MainPage.xaml.cpp
index bdcbb29..6a13b22 100644
--- a/MainPage.xaml.cpp
+++ b/MainPage.xaml.cpp
@@ -246,14 +246,6 @@ void RingClientUWP::MainPage::OnstateChange(Platform::String ^callId, RingClient
             OnsummonMessageTextPage();
         break;
     }
-    /* if the state changes to IN_PROGRESS for any peer, show the video page.
-       nb : the peer is currently selected from the SmartPannel. */
-    case CallStatus::IN_PROGRESS:
-    {
-        if (item)
-            OnsummonVideoPage();
-        break;
-    }
     default:
         break;
     }
@@ -265,14 +257,14 @@ MainPage::Application_Suspending(Object^, Windows::ApplicationModel::SuspendingE
 {
     WriteLine("Application_Suspending");
     if (Frame->CurrentSourcePageType.Name ==
-        Interop::TypeName(MainPage::typeid).Name)
+            Interop::TypeName(MainPage::typeid).Name)
     {
         if (Video::VideoManager::instance->captureManager()->captureTaskTokenSource)
             Video::VideoManager::instance->captureManager()->captureTaskTokenSource->cancel();
         //displayInformation->OrientationChanged -= displayInformationEventToken;
         auto deferral = e->SuspendingOperation->GetDeferral();
         Video::VideoManager::instance->captureManager()->CleanupCameraAsync()
-            .then([this, deferral]() {
+        .then([this, deferral]() {
             deferral->Complete();
         });
     }
@@ -292,4 +284,5 @@ MainPage::Application_VisibilityChanged(Object^ sender, VisibilityChangedEventAr
     {
         WriteLine("->Invisible");
     }
-}

+}
+
diff --git a/MainPage.xaml.h b/MainPage.xaml.h
index 554ae31..428c539 100644
--- a/MainPage.xaml.h
+++ b/MainPage.xaml.h
@@ -60,6 +60,6 @@ private:
     void OnsummonWelcomePage();
     void OnsummonVideoPage();
     void OnpressHangUpCall();
-    void OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code);
+    void OnstateChange(Platform::String ^callId, CallStatus state, int code);
 };
 }
diff --git a/RingConsolePanel.xaml.cpp b/RingConsolePanel.xaml.cpp
index 797e023..1976dc2 100644
--- a/RingConsolePanel.xaml.cpp
+++ b/RingConsolePanel.xaml.cpp
@@ -95,7 +95,7 @@ void RingConsolePanel::sendCommand()
     currentCmd = "";
     historyLevel = historyCmds.Size;
 
-    if (cmdInput == "") {
+    if (cmdInput->IsEmpty()) {
         return;
     }
     else if (cmdInput == "help") {
diff --git a/RingD.cpp b/RingD.cpp
index fba4158..1308305 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -114,14 +114,14 @@ RingD::createSIPAccount(String^ alias)
     tasksList_.push(ref new RingD::Task(Request::AddSIPAccount));
 }
 
-void RingClientUWP::RingD::refuseIncommingCall(Call^ call)
+void RingClientUWP::RingD::refuseIncommingCall(String^ callId)
 {
-    tasksList_.push(ref new RingD::Task(Request::RefuseIncommingCall, call));
+    tasksList_.push(ref new RingD::Task(Request::RefuseIncommingCall, callId));
 }
 
-void RingClientUWP::RingD::acceptIncommingCall(Call^ call)
+void RingClientUWP::RingD::acceptIncommingCall(String^ callId)
 {
-    tasksList_.push(ref new RingD::Task(Request::AcceptIncommingCall, call));
+    tasksList_.push(ref new RingD::Task(Request::AcceptIncommingCall, callId));
 }
 
 void RingClientUWP::RingD::placeCall(Contact^ contact)
@@ -137,65 +137,40 @@ void RingClientUWP::RingD::placeCall(Contact^ contact)
 
 
 
-    if (callId2 == "") {
+    if (callId2.empty()) {
         WNG_("call not created, the daemon didn't return a call Id");
         return;
     }
 
     auto callId = Utils::toPlatformString(callId2);
 
+    _callIdsList->Append(callId);
 
     //auto con = ContactsViewModel::instance->findContactByName(to);
     auto item = SmartPanelItemsViewModel::instance->findItem(contact);
     item->_callId = callId;
     MSG_("$1 place call with id : " + Utils::toString(item->_callId));
 
+    callPlaced(callId);
 
-    auto call = CallsViewModel::instance->addNewCall(accountId, callId, to);
-    call->isOutGoing = true;
-
-    if (call == nullptr) {
-        WNG_("call not created, nullptr reason");
-        return;
-    }
-
-    calling(call);
-
-}
-
-void
-RingClientUWP::RingD::cancelOutGoingCall(Call^ call)
-{
-    MSG_("1!--->> cancelOutGoingCall");
-    if (call)
-        tasksList_.push(ref new RingD::Task(Request::CancelOutGoingCall, call));
 }
 
 void RingClientUWP::RingD::cancelOutGoingCall2(String ^ callId)
 {
     MSG_("$1 cancelOutGoingCall2 : " + Utils::toString(callId));
-    tasksList_.push(ref new RingD::Task(Request::HangUpCall, callId, 0));
+    tasksList_.push(ref new RingD::Task(Request::HangUpCall, callId));
 }
 
-void
-RingClientUWP::RingD::hangUpCall(Call^ call)
-{
-    tasksList_.push(ref new RingD::Task(Request::HangUpCall, call));
-}
 
 void RingClientUWP::RingD::hangUpCall2(String ^ callId)
 {
     MSG_("$1 hangUpCall2 : "+Utils::toString(callId));
-    tasksList_.push(ref new RingD::Task(Request::HangUpCall, callId, 0));
+    tasksList_.push(ref new RingD::Task(Request::HangUpCall, callId));
 }
 
 void
 RingClientUWP::RingD::startDaemon()
 {
-    // TODO (during refactoring) : use namespace
-    /* clear the calls list and instantiate the singleton (required)  */
-    RingClientUWP::ViewModel::CallsViewModel::instance->clearCallsList();
-
     create_task([&]()
     {
         using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>;
@@ -228,7 +203,6 @@ RingClientUWP::RingD::startDaemon()
                     incomingCall(accountId2, callId2, from2);
                     stateChange(callId2, CallStatus::INCOMING_RINGING, 0);
 
-
                     auto contact = ContactsViewModel::instance->findContactByName(from2);
                     auto item = SmartPanelItemsViewModel::instance->findItem(contact);
                     item->_callId = callId2;
@@ -250,6 +224,9 @@ RingClientUWP::RingD::startDaemon()
 
                 auto state3 = getCallStatus(state2);
 
+                if (state3 == CallStatus::ENDED)
+                    DRing::hangUp(callId); // solve a bug in the daemon API.
+
 
                 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
                     CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
@@ -293,12 +270,7 @@ RingClientUWP::RingD::startDaemon()
 
                 from2 = Utils::TrimRingId2(from2);
 
-                Call^ call = CallsViewModel::instance->findCall(callId2);
 
-                if (!call)
-                    return;
-
-                String^ accountId2 = call->accountId;
                 const std::string PROFILE_VCF = "x-ring/ring.profile.vcard";
                 static const unsigned int profileSize = PROFILE_VCF.size();
 
@@ -314,7 +286,9 @@ RingClientUWP::RingD::startDaemon()
                     CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
                         CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
                     {
-                        incomingAccountMessage(accountId2, from2, payload);
+                        // DOIT ETRE DIFFEREND.... NE PAS UTILISE accoutId2
+                        //incomingAccountMessage(accountId2, from2, payload);
+                        MSG_("message recu :" + i.second);
                     }));
                 }
             }),
@@ -462,8 +436,8 @@ RingClientUWP::RingD::startDaemon()
             }
             while (true) {
                 DRing::pollEvents();
-                Sleep(1000);
                 dequeueTasks();
+                Sleep(1000);
             }
             DRing::fini();
         }
@@ -473,6 +447,7 @@ RingClientUWP::RingD::startDaemon()
 RingD::RingD()
 {
     localFolder_ = Utils::toString(ApplicationData::Current->LocalFolder->Path);
+    callIdsList_ = ref new Vector<String^>();
 }
 
 void
@@ -502,14 +477,14 @@ RingD::dequeueTasks()
         break;
         case Request::RefuseIncommingCall:
         {
-            auto callId = task->_call->callId;
+            auto callId = task->_callId;
             auto callId2 = Utils::toString(callId);
             DRing::refuse(callId2);
         }
         break;
         case Request::AcceptIncommingCall:
         {
-            auto callId = task->_call->callId;
+            auto callId = task->_callId;
             auto callId2 = Utils::toString(callId);
             DRing::accept(callId2);
         }
@@ -517,15 +492,8 @@ RingD::dequeueTasks()
         case Request::CancelOutGoingCall:
         case Request::HangUpCall:
         {
-
-            MSG_("1!--->> Request::CancelOutGoingCall");
-            auto id = task->_callId;
-            DRing::hangUp(Utils::toString(id));
-            return;
-
-            auto callId = task->_call->callId;
-            auto callId2 = Utils::toString(callId);
-            DRing::hangUp(callId2);
+            auto callId = task->_callId;
+            DRing::hangUp(Utils::toString(callId));
         }
         break;
         default:
@@ -535,7 +503,7 @@ RingD::dequeueTasks()
     }
 }
 
-CallStatus RingClientUWP::RingD::getCallStatus(String^ state)
+RingClientUWP::CallStatus RingClientUWP::RingD::getCallStatus(String^ state)
 {
     if (state == "INCOMING")
         return CallStatus::INCOMING_RINGING;
diff --git a/RingD.h b/RingD.h
index 7a22790..c1eed29 100644
--- a/RingD.h
+++ b/RingD.h
@@ -26,7 +26,7 @@ namespace RingClientUWP
 delegate void IncomingCall(String^ accountId, String^ callId, String^ from);
 delegate void StateChange(String^ callId, CallStatus state, int code);
 delegate void IncomingAccountMessage(String^ accountId, String^ from, String^ payload);
-delegate void Calling(Call^ call);
+delegate void CallPlaced(String^ callId);
 
 
 public ref class RingD sealed
@@ -54,6 +54,15 @@ public:
 
     void cancelOutGoingCall2(String^ callId); // marche
 
+internal: // why this property has to be internal and not public ?
+    property Vector<String^>^ _callIdsList
+    {
+        Vector<String^>^ get()
+        {
+            return callIdsList_;
+        }
+    }
+
 
 internal:
     /* functions */
@@ -62,13 +71,12 @@ internal:
     void sendAccountTextMessage(String^ message);
     void createRINGAccount(String^ alias);
     void createSIPAccount(String^ alias);
-    void refuseIncommingCall(Call^ call);
-    void acceptIncommingCall(Call^ call);
+    void refuseIncommingCall(String^ call);
+    void acceptIncommingCall(String^ call);
     void placeCall(Contact^ contact);
-    void cancelOutGoingCall(Call^ call);
     /*void cancelOutGoingCall2(String^ callId);*/ // marche pas
+    CallStatus getCallStatus(String^ state);
 
-    void hangUpCall(Call^ call);
     void hangUpCall2(String^ callId);
 
     /* TODO : move members */
@@ -79,7 +87,7 @@ internal:
     event IncomingCall^ incomingCall;
     event StateChange^ stateChange;
     event IncomingAccountMessage^ incomingAccountMessage;
-    event Calling^ calling;
+    event CallPlaced^ callPlaced;
 
 private:
     /* sub classes */
@@ -92,30 +100,29 @@ private:
         CancelOutGoingCall,
         HangUpCall
     };
+
+
+    Vector<String^>^ callIdsList_;
+
     ref class Task
     {
     internal:
         Task(Request r) {
             request = r;
         }
-        Task(Request r, Call^ c) {
-            request = r;
-            _call = c;
-        }
-        Task(Request r, String^ c, int i) {
+        Task(Request r, String^ c) {
             request = r;
             _callId = c;
         }
     public:
         property Request request;
-        property Call^ _call;
         property String^ _callId;
     };
 
     /* functions */
     RingD(); // singleton
     void dequeueTasks();
-    CallStatus getCallStatus(String^ state);
+//    CallStatus getCallStatus(String^ state);
 
     /* members */
     std::string localFolder_;
diff --git a/SmartPanel.xaml b/SmartPanel.xaml
index 3876183..4bda00e 100644
--- a/SmartPanel.xaml
+++ b/SmartPanel.xaml
@@ -203,65 +203,6 @@
                            Text="{x:Bind ringID_}"/>
             </Grid>
         </DataTemplate>
-        <!-- template for incoming calls. -->
-        <DataTemplate x:Key="IncomingCallTemplate" x:DataType="local:Call">
-            <Grid Width="320"
-                      HorizontalAlignment="Left"
-                      Background="DarkGray">
-                <Grid.RowDefinitions>
-                    <RowDefinition Height="30"/>
-                    <RowDefinition Height="30"/>
-                </Grid.RowDefinitions>
-                <TextBlock x:Name="_contactCallStatus_"
-                           Grid.Row="0"
-                           Foreground="White"
-                           Text="{x:Bind state, Mode=OneWay}"
-                           Visibility="Visible"
-                           HorizontalAlignment="Center">
-                </TextBlock>
-                <StackPanel Orientation="Horizontal"
-                            Grid.Row="1"
-                            HorizontalAlignment="Center">
-                    <Button x:Name="_acceptIncomingCallBtn_"
-                            Click="_acceptIncomingCallBtn__Click"
-                            VerticalAlignment="Center"
-                            HorizontalAlignment="Center"
-                            Content="Accept"/>
-                    <Button x:Name="_rejectIncomingCallBtn_"
-                            Click="_rejectIncomingCallBtn__Click"
-                            VerticalAlignment="Center"
-                            HorizontalAlignment="Center"
-                            Content="Reject"/>
-                </StackPanel>
-            </Grid>
-        </DataTemplate>
-        <!-- template for outgoing calls. -->
-        <DataTemplate x:Key="OutGoingCallTemplate" x:DataType="local:Call">
-            <Grid Width="320"
-                      HorizontalAlignment="Left"
-                      Background="DarkGray">
-                <Grid.RowDefinitions>
-                    <RowDefinition Height="30"/>
-                    <RowDefinition Height="30"/>
-                </Grid.RowDefinitions>
-                <TextBlock x:Name="_contactCallStatus_"
-                           Grid.Row="0"
-                           Foreground="White"
-                           Text="{x:Bind state, Mode=OneWay}"
-                           Visibility="Visible"
-                           HorizontalAlignment="Center">
-                </TextBlock>
-                <StackPanel Orientation="Horizontal"
-                            Grid.Row="1"
-                            HorizontalAlignment="Center">
-                    <Button x:Name="_cancelCallBtn_"
-                            Click="_cancelCallBtn__Click"
-                            VerticalAlignment="Center"
-                            HorizontalAlignment="Center"
-                            Content="Cancel"/>
-                </StackPanel>
-            </Grid>
-        </DataTemplate>
         <!-- template for smartpanelitems. -->
         <DataTemplate x:Key="SmartPanelItemsTemplate"
                       x:DataType="controls:SmartPanelItem">
@@ -348,7 +289,7 @@
                         </Grid>
                     </Grid>
                 </Grid>
-                <!-- incomming call bar. -->
+                <!-- call bar. -->
                 <Grid Width="320"
                       Grid.Row="1"
                       HorizontalAlignment="Left"
@@ -357,11 +298,11 @@
                         <RowDefinition Height="auto"/>
                         <RowDefinition Height="auto"/>
                     </Grid.RowDefinitions>
-                    <TextBlock x:Name="_incommingCallStatus_"
+                    <TextBlock x:Name="_CallStatus_"
                            Grid.Row="0"
                            Foreground="White"
-                           Text="{x:Bind _call.state, Mode=OneWay}"
-                           Visibility="{x:Bind _call.state, Converter={StaticResource _HasAnActiveCall_}, Mode=OneWay}"
+                           Text="{x:Bind _callStatus, Mode=OneWay}"
+                           Visibility="{x:Bind _callStatus, Converter={StaticResource _HasAnActiveCall_}, Mode=OneWay}"
                            HorizontalAlignment="Center">
                     </TextBlock>
                     <StackPanel Orientation="Horizontal"
@@ -370,19 +311,19 @@
                                 HorizontalAlignment="Center">
                         <Button x:Name="_acceptIncomingCallBtn_"
                             Click="_acceptIncomingCallBtn__Click"
-                            Visibility="{x:Bind _call.state, Converter={StaticResource _IncomingVisibility_}, Mode=OneWay}"
+                            Visibility="{x:Bind _callStatus, Converter={StaticResource _IncomingVisibility_}, Mode=OneWay}"
                             VerticalAlignment="Center"
                             HorizontalAlignment="Center"
                             Content="Accept"/>
                         <Button x:Name="_rejectIncomingCallBtn_"
                             Click="_rejectIncomingCallBtn__Click"
-                            Visibility="{x:Bind _call.state, Converter={StaticResource _IncomingVisibility_}, Mode=OneWay}"
+                            Visibility="{x:Bind _callStatus, Converter={StaticResource _IncomingVisibility_}, Mode=OneWay}"
                             VerticalAlignment="Center"
                             HorizontalAlignment="Center"
                             Content="Reject"/>
                         <Button x:Name="_cancelCallBtn_"
                             Click="_cancelCallBtn__Click"
-                            Visibility="{x:Bind _call.state, Converter={StaticResource _OutGoingVisibility_}, Mode=OneWay}"
+                            Visibility="{x:Bind _callStatus, Converter={StaticResource _OutGoingVisibility_}, Mode=OneWay}"
                             VerticalAlignment="Center"
                             HorizontalAlignment="Center"
                             Content="Cancel"/>
diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp
index d1d01f5..b91a2ac 100644
--- a/SmartPanel.xaml.cpp
+++ b/SmartPanel.xaml.cpp
@@ -62,9 +62,9 @@ SmartPanel::SmartPanel()
         _accountsListScrollView_->UpdateLayout();
         _accountsListScrollView_->ScrollToVerticalOffset(_accountsListScrollView_->ScrollableHeight);
     });
-    CallsViewModel::instance->callRecieved += ref new RingClientUWP::CallRecieved([&](
-    Call^ call) {
-        auto from = call->from;
+    RingD::instance->incomingCall += ref new RingClientUWP::IncomingCall([&](
+    String^ accountId, String^ callId, String^ from) {
+        ///auto from = call->from;
         auto contact = ContactsViewModel::instance->findContactByName(from);
 
         if (contact == nullptr)
@@ -76,26 +76,36 @@ SmartPanel::SmartPanel()
         }
 
         auto item = SmartPanelItemsViewModel::instance->findItem(contact);
-        item->_call = call;
+        item->_callId = callId;
 
     });
     RingD::instance->stateChange += ref new StateChange([this](String^ callId, CallStatus state, int code) {
-        auto call = CallsViewModel::instance->findCall(callId);
 
-        if (call == nullptr)
-            return;
-
-        auto item = SmartPanelItemsViewModel::instance->findItem(call);
+        auto item = SmartPanelItemsViewModel::instance->findItem(callId);
 
         if (!item) {
             WNG_("item not found");
             return;
         }
 
-        call->state = state;
+        item->_callStatus = state;
 
-        if (state == CallStatus::IN_PROGRESS)
-            _smartList_->SelectedIndex = SmartPanelItemsViewModel::instance->getIndex(call);
+        switch (state) {
+        case CallStatus::NONE:
+        case CallStatus::ENDED:
+        {
+            item->_callId = "";
+            break;
+        }
+        case CallStatus::IN_PROGRESS:
+        {
+            _smartList_->SelectedItem = item;
+            summonVideoPage();
+            break;
+        }
+        default:
+            break;
+        }
 
     });
 
@@ -106,29 +116,7 @@ SmartPanel::SmartPanel()
         SmartPanelItemsViewModel::instance->itemsList->Append(smartPanelItem);
     });
 
-    RingD::instance->calling += ref new RingClientUWP::Calling([&](
-    Call^ call) {
-        MSG_("!--->> Calling lambda from smartpanel");
-        auto from = call->from;
-        auto contact = ContactsViewModel::instance->findContactByName(from);
-
-        if (contact == nullptr) {
-            WNG_("cannot call the peer, contact not found!");
-            return;
-        }
-
-        auto item = SmartPanelItemsViewModel::instance->findItem(contact);
-
-        if (item == nullptr) {
-            WNG_("cannot call the peer, smart panel item not found!");
-            return;
-        }
-
-        call->state = CallStatus::SEARCHING;
-        MSG_("!--->> should be Searching");
 
-        item->_call = call;
-    });
 
 }
 
@@ -256,21 +244,16 @@ SmartPanel::_smartList__SelectionChanged(Platform::Object^ sender, Windows::UI::
         return;
     }
 
-    auto call = item->_call;
     auto contact = item->_contact;
 
-    if (call) {
-        auto state = call->state;
-
-        if (state == CallStatus::IN_PROGRESS) {
-            if (contact) {
-                contact->_unreadMessages = 0;
-                ContactsViewModel::instance->saveContactsToFile();
-            }
-
-            summonVideoPage();
-            return;
+    if (item->_callStatus == CallStatus::IN_PROGRESS) {
+        if (contact) {
+            contact->_unreadMessages = 0;
+            ContactsViewModel::instance->saveContactsToFile();
         }
+
+        summonVideoPage();
+        return;
     }
 
     if (contact) {
@@ -307,7 +290,7 @@ SmartPanel::_accountList__SelectionChanged(Platform::Object^ sender, Windows::UI
 void RingClientUWP::Views::SmartPanel::_ringTxtBx__KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
 {
     /* add contact, test purpose but will be reused later in some way */
-    if (e->Key == Windows::System::VirtualKey::Enter && _ringTxtBx_->Text != "") {
+    if (e->Key == Windows::System::VirtualKey::Enter && !_ringTxtBx_->Text->IsEmpty()) {
         ContactsViewModel::instance->addNewContact(_ringTxtBx_->Text, _ringTxtBx_->Text);
         _ringTxtBx_->Text = "";
     }
@@ -319,32 +302,28 @@ void RingClientUWP::Views::SmartPanel::_ringTxtBx__Click(Platform::Object^ sende
     _ringTxtBx_->Text = "";
 }
 
-// REFACTO : change the name IncomingCall if used with OutGoingCall too.
-void RingClientUWP::Views::SmartPanel::_rejectIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void
+RingClientUWP::Views::SmartPanel::_rejectIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
 {
     auto button = dynamic_cast<Button^>(e->OriginalSource);
     if (button) {
         auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);
         if (item) {
-            auto call = item->_call;
-            if (call)
-                RingD::instance->refuseIncommingCall(call);
-            //call->refuse();
+            auto callId = item->_callId;
+            RingD::instance->refuseIncommingCall(callId);
         }
     }
 }
 
-
-void RingClientUWP::Views::SmartPanel::_acceptIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+void
+RingClientUWP::Views::SmartPanel::_acceptIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
 {
     auto button = dynamic_cast<Button^>(e->OriginalSource);
     if (button) {
         auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);
         if (item) {
-            auto call = item->_call;
-            if (call)
-                RingD::instance->acceptIncommingCall(call);
-            //call->accept();
+            auto callId = item->_callId;
+            RingD::instance->acceptIncommingCall(callId);
         }
     }
 }
@@ -352,9 +331,11 @@ void RingClientUWP::Views::SmartPanel::_acceptIncomingCallBtn__Click(Platform::O
 void
 SmartPanel::_callContact__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
 {
-    MSG_("!--->> _callContact__Click");
     auto button = dynamic_cast<Button^>(e->OriginalSource);
     if (button) {
+        /* force to hide the button, avoid attempting to call several times... */
+        button->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+
         auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);
         if (item) {
             auto contact = item->_contact;
@@ -364,32 +345,27 @@ SmartPanel::_callContact__Click(Platform::Object^ sender, Windows::UI::Xaml::Rou
     }
 }
 
-
 void RingClientUWP::Views::SmartPanel::_cancelCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
 {
     auto button = dynamic_cast<Button^>(e->OriginalSource);
     if (button) {
         auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);
         if (item) {
-            auto call = item->_call;
             RingD::instance->cancelOutGoingCall2(item->_callId);
-
+            item->_callStatus = CallStatus::TERMINATING;
             return;
-            if (call)
-                RingD::instance->cancelOutGoingCall(call);
-            //call->cancel();
         }
     }
 }
 
-
 void RingClientUWP::Views::SmartPanel::Grid_PointerEntered(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
 {
     auto grid = dynamic_cast<Grid^>(sender);
     auto listBoxItem = dynamic_cast<ListBoxItem^>(sender);
     auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext);
 
-    item->_hovered = Windows::UI::Xaml::Visibility::Visible;
+    if (item->_callId->IsEmpty())
+        item->_hovered = Windows::UI::Xaml::Visibility::Visible;
 }
 
 
@@ -418,6 +394,7 @@ void RingClientUWP::Views::SmartPanel::_contactItem__PointerReleased(Platform::O
 Object ^ RingClientUWP::Views::IncomingVisibility::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)
 {
     auto state = static_cast<CallStatus>(value);
+
     if (state == CallStatus::INCOMING_RINGING)
         return  Windows::UI::Xaml::Visibility::Visible;
     else
@@ -464,7 +441,6 @@ Object ^ RingClientUWP::Views::HasAnActiveCall::Convert(Object ^ value, Windows:
 Object ^ RingClientUWP::Views::HasAnActiveCall::ConvertBack(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)
 {
     throw ref new Platform::NotImplementedException();
-
 }
 
 RingClientUWP::Views::HasAnActiveCall::HasAnActiveCall()
diff --git a/SmartPanelItem.cpp b/SmartPanelItem.cpp
index 35c77de..ebf3eee 100644
--- a/SmartPanelItem.cpp
+++ b/SmartPanelItem.cpp
@@ -31,10 +31,9 @@ using namespace ViewModel;
 
 SmartPanelItem::SmartPanelItem()
 {
-    /* create an empty call to avoid the call bar */
-    _call = ref new Call("", "", "");
     _callId = "";
 
+    RingD::instance->callPlaced += ref new RingClientUWP::CallPlaced(this, &RingClientUWP::Controls::SmartPanelItem::OncallPlaced);
 }
 
 void
@@ -47,4 +46,11 @@ SmartPanelItem::NotifyPropertyChanged(String^ propertyName)
     {
         PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
     }));
-}
\ No newline at end of file
+}
+
+void RingClientUWP::Controls::SmartPanelItem::OncallPlaced(Platform::String ^callId)
+{
+    if (_callId == callId) {
+        _callStatus = CallStatus::SEARCHING;
+    }
+}
diff --git a/SmartPanelItem.h b/SmartPanelItem.h
index 45a7e39..88cb486 100644
--- a/SmartPanelItem.h
+++ b/SmartPanelItem.h
@@ -32,7 +32,7 @@ public:
 
     virtual event PropertyChangedEventHandler^ PropertyChanged;
     property Contact^ _contact;
-    property Call^ _call
+    /*property Call^ _call
     {
         Call^ get()
         {
@@ -43,7 +43,7 @@ public:
             call_ = value;
             PropertyChanged(this, ref new PropertyChangedEventArgs("_call"));
         }
-    }
+    }*/
     property Visibility _hovered
     {
         Visibility get()
@@ -57,15 +57,33 @@ public:
         }
     }
 
-    property String^ _callId;
+    property String^ _callId; /*{
+        String^ get() {
+            return callId_;
+        }
+        void set(String^ value) {
+            _callId = value;
+        }
+    }*/
+    property CallStatus _callStatus {
+        CallStatus get() {
+            return callStatus_;
+        }
+        void set(CallStatus value) {
+            callStatus_ = value;
+            PropertyChanged(this, ref new PropertyChangedEventArgs("_callStatus"));
+        }
+    }
 
 protected:
     void NotifyPropertyChanged(String^ propertyName);
 
 private:
-    Call^ call_;
     Visibility hovered_ = Visibility::Collapsed;
+    CallStatus callStatus_;
+    String^ callId_;
 
+    void OncallPlaced(Platform::String ^callId);
 };
 }
 }
diff --git a/SmartPanelItemsViewModel.cpp b/SmartPanelItemsViewModel.cpp
index bdb2406..e567398 100644
--- a/SmartPanelItemsViewModel.cpp
+++ b/SmartPanelItemsViewModel.cpp
@@ -36,10 +36,10 @@ SmartPanelItemsViewModel::SmartPanelItemsViewModel()
 }
 
 SmartPanelItem^
-SmartPanelItemsViewModel::findItem(Call^ call)
+SmartPanelItemsViewModel::findItem(String^ callId)
 {
     for each (SmartPanelItem^ item in itemsList)
-        if (item->_call == call)
+        if (item->_callId == callId)
             return item;
 
     return nullptr;
@@ -56,11 +56,11 @@ SmartPanelItemsViewModel::findItem(Contact^ contact)
 }
 
 unsigned int
-SmartPanelItemsViewModel::getIndex(Call^ call)
+SmartPanelItemsViewModel::getIndex(String^ callId)
 {
     unsigned int i;
     for (i = 0; i < itemsList_->Size; i++) {
-        if (itemsList_->GetAt(i)->_call == call)
+        if (itemsList_->GetAt(i)->_callId == callId)
             break;
     }
     return i;
diff --git a/SmartPanelItemsViewModel.h b/SmartPanelItemsViewModel.h
index 029b165..f77d3a0 100644
--- a/SmartPanelItemsViewModel.h
+++ b/SmartPanelItemsViewModel.h
@@ -27,6 +27,7 @@ using namespace RingClientUWP::Controls;
 namespace RingClientUWP
 {
 namespace ViewModel {
+
 public ref class SmartPanelItemsViewModel sealed
 {
 internal:
@@ -41,9 +42,9 @@ internal:
     }
 
     /* functions */
-    SmartPanelItem^ findItem(Call^ call);
+    SmartPanelItem^ findItem(String^ callId);
     SmartPanelItem^ findItem(Contact^ contact);
-    unsigned int getIndex(Call^ call);
+    unsigned int getIndex(String^ callId);
     unsigned int getIndex(Contact^ contact);
 
     property Vector<SmartPanelItem^>^ itemsList
diff --git a/VideoPage.xaml.cpp b/VideoPage.xaml.cpp
index 657d1c1..1d44ac6 100644
--- a/VideoPage.xaml.cpp
+++ b/VideoPage.xaml.cpp
@@ -203,16 +203,7 @@ void RingClientUWP::Views::VideoPage::_btnCancel__Click(Platform::Object^ sender
 void RingClientUWP::Views::VideoPage::_btnHangUp__Tapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e)
 {
     auto item = SmartPanelItemsViewModel::instance->_selectedItem;
-    auto call = item->_call;
-
-    /*if (call)
-        RingD::instance->hangUpCall(call);*/
-
-    if (item->_callId != "") {
-        MSG_("$1 item->callid != vide ");
-        RingD::instance->hangUpCall2(item->_callId);
-        item->_callId = "";
-    }
+    RingD::instance->hangUpCall2(item->_callId);
 
     pressHangUpCall();
 }
diff --git a/pch.h b/pch.h
index 20d873b..9bd464e 100644
--- a/pch.h
+++ b/pch.h
@@ -26,13 +26,13 @@
 #include <sstream>
 #include <string>
 
+/* project's globals */
+#include "Globals.h"
 
 /* required by generated headers. */
 #include "App.xaml.h"
 #include "Account.h"
 #include "AccountsViewModel.h"
-#include "Call.h"
-#include "CallsViewModel.h"
 #include "Contact.h"
 #include "ContactsViewModel.h"
 #include "Conversation.h"
diff --git a/ring-client-uwp.vcxproj b/ring-client-uwp.vcxproj
index 6f1281f..5a7fe1b 100644
--- a/ring-client-uwp.vcxproj
+++ b/ring-client-uwp.vcxproj
@@ -161,11 +161,10 @@
   <ItemGroup>
     <ClInclude Include="Account.h" />
     <ClInclude Include="AccountsViewModel.h" />
-    <ClInclude Include="Call.h" />
-    <ClInclude Include="CallsViewModel.h" />
     <ClInclude Include="Contact.h" />
     <ClInclude Include="ContactsViewModel.h" />
     <ClInclude Include="Conversation.h" />
+    <ClInclude Include="Globals.h" />
     <ClInclude Include="LoadingPage.xaml.h">
       <DependentUpon>LoadingPage.xaml</DependentUpon>
     </ClInclude>
@@ -275,8 +274,6 @@
       <DependentUpon>App.xaml</DependentUpon>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\ring-daemon\MSVC;..\ring-daemon\src\media;..\ring-daemon\src;..\ring-daemon\src\dring;..\ring-daemon\contrib\include;..\ring-daemon\contrib\include\pjlib;..\ring-daemon\contrib\pjproject\third_party\speex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
-    <ClCompile Include="Call.cpp" />
-    <ClCompile Include="CallsViewModel.cpp" />
     <ClCompile Include="Contact.cpp" />
     <ClCompile Include="ContactsViewModel.cpp" />
     <ClCompile Include="Conversation.cpp" />
diff --git a/ring-client-uwp.vcxproj.filters b/ring-client-uwp.vcxproj.filters
index 2d88f46..e28e7a0 100644
--- a/ring-client-uwp.vcxproj.filters
+++ b/ring-client-uwp.vcxproj.filters
@@ -83,15 +83,9 @@
     <ClCompile Include="Conversation.cpp">
       <Filter>Model</Filter>
     </ClCompile>
-    <ClCompile Include="CallsViewModel.cpp">
-      <Filter>ModelViews</Filter>
-    </ClCompile>
     <ClCompile Include="UserPreferences.cpp">
       <Filter>Common</Filter>
     </ClCompile>
-    <ClCompile Include="Call.cpp">
-      <Filter>Model</Filter>
-    </ClCompile>
     <ClCompile Include="SmartPanelItem.cpp">
       <Filter>Controls</Filter>
     </ClCompile>
@@ -143,18 +137,12 @@
     </ClInclude>
     <ClInclude Include="LoadingPage.xaml.h" />
     <ClInclude Include="Wizard.xaml.h" />
-    <ClInclude Include="CallsViewModel.h">
-      <Filter>ModelViews</Filter>
-    </ClInclude>
     <ClInclude Include="Conversation.h">
       <Filter>Model</Filter>
     </ClInclude>
     <ClInclude Include="UserPreferences.h">
       <Filter>Common</Filter>
     </ClInclude>
-    <ClInclude Include="Call.h">
-      <Filter>Model</Filter>
-    </ClInclude>
     <ClInclude Include="SmartPanelItem.h">
       <Filter>Controls</Filter>
     </ClInclude>
@@ -173,6 +161,9 @@
     <ClInclude Include="Video.h">
       <Filter>Media\Video</Filter>
     </ClInclude>
+    <ClInclude Include="Globals.h">
+      <Filter>Common</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Image Include="Assets\LockScreenLogo.scale-200.png">
-- 
GitLab