[Back]

//
// DotNetNuke - http:'www.dotnetnuke.com
// Copyright (c) 2002-2009
// by DotNetNuke Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// Based on
// Silverlight2Chat
// Copyright (c) 2009
// by Junnark Vicencio 
//
// The Code Project Open License (CPOL) 1.02
// http://www.codeproject.com/info/cpol10.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows.Threading;
using System.ServiceModel;
using DNNSilverlightChat.ChatWebService;

namespace DNNSilverlightChat
{
    public partial class Page : UserControl
    {
        public int intPortalID;
        public int intModuleId;
        public int intUserID;
        public string strPassword;
        public int intRefresh;
        public string strDisplayName;
        public string strWebServiceURL;

        DispatcherTimer timer;
        private bool _isWithBackground = false;
        private int _lastMessageId = 0;
        private int _userID = 0;
        private DateTime _dtTimeUserJoined;

        public Page(string PortalID, string ModuleId, string UserID, string Password, string Refresh, string DisplayName, string WebServiceURL)
        {
            // Required to initialize variables
            InitializeComponent();

            intPortalID = Convert.ToInt32(PortalID);
            intModuleId = Convert.ToInt32(ModuleId);
            intUserID = Convert.ToInt32(UserID);
            strPassword = Password;
            intRefresh = Convert.ToInt32(Refresh);
            strDisplayName = DisplayName;
            strWebServiceURL = WebServiceURL;
        }

        #region LayoutRoot_Loaded
        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            if (intUserID > 0)
            {
                _dtTimeUserJoined = DateTime.Now;
                TxtMessage.Focus();
                InsertNewlyJoinedMessage();
                GetUsers();
                SetTimer();
            }
            else
            {
                if (intUserID == 0)
                {
                    Title.Text = "Max numbers of users is reached.";
                }
                else
                {
                    Title.Text = "Must log in to use Chat";
                }
                SidePanel.Visibility = Visibility.Collapsed;
                CbxFontColor.Visibility = Visibility.Collapsed;
                TxtMessage.Visibility = Visibility.Collapsed;
                SvwrUserList.Visibility = Visibility.Collapsed;
                SvwrUserList.Visibility = Visibility.Collapsed;
                BtnSend.Visibility = Visibility.Collapsed;
                SpnlMessages.Visibility = Visibility.Collapsed;
                SvwrMessages.Visibility = Visibility.Collapsed;
            }
        }       
        #endregion 

        #region Timer
        private void SetTimer()
        {
            timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 0, intRefresh, 0);
            timer.Tick += new EventHandler(TimerTick);
            timer.Start();
        }

        void TimerTick(object sender, EventArgs e)
        {            
            GetMessages();
            GetUsers();
        }
        #endregion

        #region GetUsers
        private void GetUsers()
        {
            var proxy = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceURL);
            proxy.Endpoint.Address = MyEndpointAddress;
            proxy.GetUsersCompleted += new EventHandler<GetUsersCompletedEventArgs>(proxy_GetUsersCompleted);
            proxy.GetUsersAsync(intPortalID, intModuleId, intUserID, strPassword);
        }

        void proxy_GetUsersCompleted(object sender, GetUsersCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                ObservableCollection<DNNChatLoggedInUsers> users = e.Result;
                ItmcUserList.ItemsSource = users;
            }
        } 
        #endregion

        #region InsertNewlyJoinedMessage
        private void InsertNewlyJoinedMessage()
        {
            string message = "joined the room.";
            var proxy = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceURL);
            proxy.Endpoint.Address = MyEndpointAddress;
            proxy.InsertMessageAsync(intPortalID, intModuleId, intUserID, strPassword, _userID, message, "Gray");
        } 
        #endregion

        #region InsertMessage
        private void InsertMessage(string strMessage)
        {
            var proxy = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceURL);
            proxy.Endpoint.Address = MyEndpointAddress;
            proxy.InsertMessageAsync(intPortalID, intModuleId, intUserID, strPassword, _userID, strMessage, CbxFontColor.SelectionBoxItem.ToString());
        }
        #endregion

        #region GetMessages
        private void GetMessages()
        {
            var proxy = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceURL);
            proxy.Endpoint.Address = MyEndpointAddress;
            proxy.GetMessagesCompleted += new EventHandler<GetMessagesCompletedEventArgs>(proxy_GetMessagesCompleted);
            proxy.GetMessagesAsync(intPortalID, intModuleId, intUserID, strPassword, _lastMessageId, _dtTimeUserJoined);
        }

        void proxy_GetMessagesCompleted(object sender, GetMessagesCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                ObservableCollection<MessageContract> messages = e.Result;
                DisplayMessages(messages);
            }
        }
        #endregion

        #region DisplayMessages
        private void DisplayMessages(ObservableCollection<MessageContract> messages)
        {
            foreach (var message in messages)
            {
                DisplayMessage(message);
            }

            SetScrollBarToBottom();
            TxtMessage.Focus();
        }

        private void DisplayMessage(MessageContract message)
        {
            // add a horizontal stack panel
            StackPanel sp = new StackPanel();
            sp.Orientation = Orientation.Horizontal;
            sp.HorizontalAlignment = HorizontalAlignment.Left;
            sp.Width = SpnlMessages.ActualWidth;

            // put an alternating background
            if (!_isWithBackground)
                sp.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(100, 235, 235, 235));

            // add a TextBlock to hold the user's name to the stack panel
            TextBlock name = new TextBlock();
            name.Text = String.Format("{0} :", message.UserName);
            name.FontSize = 12.0;
            name.FontWeight = FontWeights.Bold;
            name.Padding = new Thickness(4, 8, 0, 8);

            if (message.Color == "Gray")
                name.Foreground = new SolidColorBrush(Colors.Gray);
            else
                name.Foreground = new SolidColorBrush(Colors.Black);

            sp.Children.Add(name);

            // add a TextBox to hold the user's message to the stack panel
            TextBox text = new TextBox();
            text.BorderBrush = new SolidColorBrush(Colors.Transparent);
            text.FontSize = 12.0;
            text.Text = message.Text.Trim();
            text.VerticalAlignment = VerticalAlignment.Top;
            text.Width = SpnlMessages.ActualWidth - name.ActualWidth;
            text.TextWrapping = TextWrapping.Wrap;
            text.Margin = new Thickness(0, 4, 4, 0);
            text.IsReadOnly = true;

            // change text color based on the user's chosen color
            if (message.Color == "Red")
                text.Foreground = new SolidColorBrush(Colors.Red);
            else if (message.Color == "Blue")
                text.Foreground = new SolidColorBrush(Colors.Blue);
            else if (message.Color == "Gray")
                text.Foreground = new SolidColorBrush(Colors.Gray);
            else
                text.Foreground = new SolidColorBrush(Colors.Black);

            // put an alternating background
            if (!_isWithBackground)
            {
                text.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(100, 235, 235, 235));
                _isWithBackground = true;
            }
            else
            {
                _isWithBackground = false;
            }

            sp.Children.Add(text);

            // add the horizontal stack panel to the base stack panel
            SpnlMessages.Children.Add(sp);

            // remember the last message id 
            if (message.MessageID > _lastMessageId)
            {
                _lastMessageId = message.MessageID;
            }
        }
        #endregion

        #region SetScrollBarToBottom
        private void SetScrollBarToBottom()
        {
            // set the scroll bar to the bottom
            SvwrMessages.UpdateLayout();
            SvwrMessages.ScrollToVerticalOffset(double.MaxValue);
        } 
        #endregion

        #region TxtMessage_KeyDown
        private void TxtMessage_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                SendMessage();
            }
        } 
        #endregion

        #region BtnSend_Click
        private void BtnSend_Click(object sender, RoutedEventArgs e)
        {
            SendMessage();
        } 
        #endregion

        #region SendMessage
        private void SendMessage()
        {
            if (!String.IsNullOrEmpty(TxtMessage.Text))
            {
                string strMessage = TxtMessage.Text;
                // Show the message
                MessageContract objInsertMessage = new MessageContract();
                objInsertMessage.MessageID = _lastMessageId;
                objInsertMessage.Text = strMessage;
                objInsertMessage.UserName = strDisplayName;
                objInsertMessage.Color = CbxFontColor.SelectionBoxItem.ToString();
                objInsertMessage.TimeStamp = DateTime.Now;

                DisplayMessage(objInsertMessage);

                SetScrollBarToBottom();
                TxtMessage.Text = String.Empty;
                TxtMessage.Focus();

                InsertMessage(strMessage);
                TxtMessage.Text = String.Empty;
                GetMessages();
                GetUsers();
            }
        } 
        #endregion

        #region BtnLogOut_Click
        private void BtnLogOut_Click(object sender, RoutedEventArgs e)
        {
            timer.Stop();

            var proxy = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceURL);
            proxy.Endpoint.Address = MyEndpointAddress;
            proxy.LogOutUserAsync(intPortalID, intModuleId, intUserID, strPassword, intUserID);

            // Logout
            Title.Text = "Refresh page to use Chat";
            SidePanel.Visibility = Visibility.Collapsed;
            CbxFontColor.Visibility = Visibility.Collapsed;
            TxtMessage.Visibility = Visibility.Collapsed;
            SvwrUserList.Visibility = Visibility.Collapsed;
            SvwrUserList.Visibility = Visibility.Collapsed;
            BtnSend.Visibility = Visibility.Collapsed;
            SpnlMessages.Visibility = Visibility.Collapsed;
            SvwrMessages.Visibility = Visibility.Collapsed;
        } 
        #endregion

    }
}