using System;
using System.ComponentModel;
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.Media.Imaging;
using System.Windows.Shapes;

using Facebook.Rest;
using Facebook.Schema;
using Facebook.Session;
using Facebook.Utility;

namespace FacebookMemoryPartII
{
    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.btnFriends.Click += new RoutedEventHandler(btnFriends_Click);
        }

        void btnFriends_Click(object sender, RoutedEventArgs e)
        {
            this.sbTransitionOutLeft.Stop();
            this.sbTransitionOutLeftDouble.SetValue(Storyboard.TargetNameProperty, "ucUserInformation");
            this.sbTransitionOutLeft.Begin();

            this.sbTransitionInFromRight.Stop();
            this.sbTransitionInFromRightDouble.SetValue(Storyboard.TargetNameProperty, "ucPhotoAlbum");
            this.sbTransitionInFromRight.Begin();

            _facebookApi.Friends.GetAsync((long)_currentUser.uid, GetFriendsCompleted, null);
        }

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

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

        void GetAlbumsCompleted(IList<album> albums, object state, FacebookException e)
        {
            if (e == null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    if (albums.Count > 0)
                    {
                        // get the photos from the first album, which is usually the profile pictures
                        _facebookApi.Photos.GetAsync(string.Empty, albums[0].aid, new List<string>(), GetPhotosCompleted, 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 albums: " + e.Message));
            }
        }

        void GetFriendsCompleted(IList<long> uids, object state, FacebookException e)
        {
            if (e == null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    this.txtStatus.Text = "Loading Photos...";

                    // get the albums for our first 20 friends
                    for (int x = 0; x < 20; x++)
                    {
                        _facebookApi.Photos.GetAlbumsAsync(uids[x], GetAlbumsCompleted, 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 friends: " + e.Message));
            }
        }

        void GetPhotosCompleted(IList<photo> photos, object state, FacebookException e)
        {
            if (e == null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    // create a new image
                    Image i = new Image();
                    i.Source = new BitmapImage(new Uri(photos[0].src));
                    i.Width = 140;
                    i.Height = 140;
                    i.Stretch = Stretch.Uniform;
                    i.Margin = new Thickness(0, 0, 5, 0);

                    // add the image to our user control
                    this.ucPhotoAlbum.AddPhoto(i);
                });
            }
            else
            {
                // if any errors occurred, invoke a call back to the UI thread and show the error message
                Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting photos: " + e.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.sbFadeInGetFriends.Begin();
                });
            }
            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 GetLoggedInUserCompleted(long userId, object state, FacebookException e)
        {
            // check that no errors have occurred
            if (e == null)
            {
                Dispatcher.BeginInvoke(() => this.txtStatus.Text = "Get loggin 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 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);
        }
    }
}
