using System;
using System.Collections.Generic;
using System.ComponentModel;
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 Facebook.Rest;
using Facebook.Schema;
using Facebook.Session;
using Facebook.Utility;
using System.Windows.Media.Imaging;

namespace FacebookMemoryPartIII
{
    public partial class MainPage : UserControl
    {
        #region Constants

        private const string APPLICATION_KEY = "YOUR_APPLICATION_KEY";

        #endregion

        #region Private

        private Api _facebookApi;
        private user _currentUser;
        private readonly BrowserSession _browserSession;

        #endregion

        public MainPage()
        {
            InitializeComponent();

            _browserSession = new BrowserSession(APPLICATION_KEY);
            _browserSession.LoginCompleted += new EventHandler<AsyncCompletedEventArgs>(LoginCompleted);

            this.btnLogin.Click += new RoutedEventHandler(btnLogin_Click);
            this.btnStream.Click += new RoutedEventHandler(btnStream_Click);
            this.btnStatus.Click += new RoutedEventHandler(btnStatus_Click);
        }

        void btnStatus_Click(object sender, RoutedEventArgs e)
        {
            this.txtStatus.Text = "Updating status";

            _facebookApi.Status.SetAsync("Testing setting my status from the Silverlight Facebook SDK", SetStatusCompleted, null);
        }

        void btnStream_Click(object sender, RoutedEventArgs e)
        {
            this.txtStatus.Text = "Publishing to Wall and News Feed";

            // create new attachment
            attachment a = new attachment();
            a.name = "This is a Test";
            a.caption = "This is cool";
            a.href = "http://www.evanjohnston.com";
            a.description = "Here is a description that goes with this post. Here is more content to make this longer.";

            // create new attachment media
            attachment_media_image i = new attachment_media_image();
            i.href = "http://www.evanjohnston.com";
            i.src = "http://www.evanjohnston.com/misc/cheerssmaller.jpg";
            i.type = attachment_media_type.image;

            // create new list of attachment media
            List<attachment_media> media = new List<attachment_media>();
            media.Add(i);

            // add the media to the attachment
            a.media = media;

            // create message string
            string message = "Testing publishing to the stream from the Silverlight Facebook SDK.";
            
            _facebookApi.Stream.PublishAsync(message, a, new List<action_link>(), "", 0, StreamPublishCompleted, null);
        }

        void SetStatusCompleted(bool status, object state, FacebookException e)
        {
            if (e == null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    this.txtStatus.Text = "";

                    // show message that status was updated
                    MessageBox.Show("Your status was successfully updated");
                });
            }
            else
            {
                // if any errors occurred, invoke a call back to the UI thread and show the error message
                Dispatcher.BeginInvoke(() => MessageBox.Show("Error setting status:\n\n" + e.Message));
            }
        }

        void StreamPublishCompleted(string status, object state, FacebookException e)
        {
            if (e == null)
            {
                Dispatcher.BeginInvoke(() => 
                {
                    this.txtStatus.Text = "";

                    // show message that message was published
                    MessageBox.Show("Message was published to stream");
                });
            }
            else
            {
                // if any errors occurred, invoke a call back to the UI thread and show the error message
                Dispatcher.BeginInvoke(() => MessageBox.Show("Error publishing to stream:\n\n" + e.Message));
            }
        }

        void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            _browserSession.Login();

            this.txtStatus.Text = "Logging in...";
        }

        void GetLoggedInUserCompleted(long userId, object state, FacebookException e)
        {
            // check that no errors have occurred
            if (e == null)
            {
                Dispatcher.BeginInvoke(() => this.txtStatus.Text = "Get logged in user complete. Getting user information...");

                // retrieve user information
                _facebookApi.Users.GetInfoAsync(userId, GetUserInfoCompleted, null);
            }
            else
            {
                // if any errors occurred, invoke a call back to the UI thread and show the error message
                Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting logged in user:\n\n" + e.InnerException.Message));
            }
        }

        void GetUserInfoCompleted(IList<user> userDetails, object state, FacebookException e)
        {
            if (e == null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    // set our user object
                    this._currentUser = userDetails[0];

                    // set user information data context
                    this.ucUserInformation.DataContext = _currentUser.current_location;
                    this.ucUserInformation.txtWelcome.Text = "Welcome " + _currentUser.name + "!";
                    this.ucUserInformation.imgProfile.Source = new BitmapImage(new Uri(_currentUser.pic_square));

                    this.txtStatus.Text = "";

                    this.btnStream.IsEnabled = true;
                    this.btnStatus.IsEnabled = true;
                });
            }
            else
            {
                // if any errors occurred, invoke a call back to the UI thread and show the error message
                Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting user info:\n\n" + e.Message));
            }
        }

        void LoginCompleted(object sender, AsyncCompletedEventArgs e)
        {
            // create new instance of facebook api
            _facebookApi = new Api(_browserSession);

            // retrieve the logged in user
            _facebookApi.Users.GetLoggedInUserAsync(GetLoggedInUserCompleted, null);
        }
    }
}
