#region File Description
//-----------------------------------------------------------------------------
// MainMenuScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.GamerServices;
#endregion

namespace FredriksdalAssault2
{
    /// <summary>
    /// The main menu screen is the first thing displayed when the game starts up.
    /// </summary>
    class MainMenuScreen : MenuScreen
    {
        
        #region Variables

        MenuEntry buyMenuEntry;
        bool isTrialGame = true;
        
        #endregion

        #region Initialization

        /// <summary>
        /// Constructor fills in the menu contents.
        /// </summary>
        public MainMenuScreen()
            : base(Resources.MainMenu)
        {
            // Create our menu entries.
            MenuEntry splitScreenMenuEntry = new MenuEntry(Resources.SplitScreenGame);
            MenuEntry systemLinkMenuEntry = new MenuEntry(Resources.SystemLink);
            MenuEntry liveMenuEntry = new MenuEntry(Resources.PlayerMatch);
            MenuEntry optionsMenuEntry = new MenuEntry(Resources.Options);
            buyMenuEntry = new MenuEntry("Buy this game");
            MenuEntry exitMenuEntry = new MenuEntry(Resources.Exit);

            // Hook up menu event handlers.
            splitScreenMenuEntry.Selected += SplitScreenMenuEntrySelected;
            systemLinkMenuEntry.Selected += SystemLinkMenuEntrySelected; 
            liveMenuEntry.Selected += LiveMenuEntrySelected;
            optionsMenuEntry.Selected += OptionsMenuEntrySelected;
            buyMenuEntry.Selected += ShowMarketPlace;
            exitMenuEntry.Selected += OnCancel;

            // Add entries to the menu.
            MenuEntries.Add(splitScreenMenuEntry);
            MenuEntries.Add(systemLinkMenuEntry);
            MenuEntries.Add(liveMenuEntry);
            MenuEntries.Add(optionsMenuEntry);
            MenuEntries.Add(buyMenuEntry);
            MenuEntries.Add(exitMenuEntry);
        
        }

        #endregion

        #region Update

        /// <summary>
        /// Update the main menu screen.
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="otherScreenHasFocus"></param>
        /// <param name="coveredByOtherScreen"></param>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            // Show the buy menu entry if the game is a trial game.
            if (this.isTrialGame == true)
            {
                if (Guide.IsTrialMode == false)
                {
                    MenuEntries.Remove(buyMenuEntry);
                    this.isTrialGame = false;
                }
            }
        } // End of the Update method.
        
        #endregion

        #region Handle Input


        ///// <summary>
        ///// Event handler for when the Single Player menu entry is selected.
        ///// </summary>
        //void SinglePlayerMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        //{
        //    LoadingScreen.Load(ScreenManager, true, e.PlayerIndex,
        //                       new GameplayScreen(null));
        //}

        /// <summary>
        /// Event handler for when the Split screen menu entry is selected.
        /// </summary>
        void SplitScreenMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            
            // First, we need to make sure a suitable gamer profile is signed in.
            ProfileSignInScreen profileSignIn = new ProfileSignInScreen(NetworkSessionType.Local);

            // Hook up an event so once the ProfileSignInScreen is happy,
            // it will activate the StartSplitScreenSessionOperation.
            profileSignIn.ProfileSignedIn += delegate
            {
                // Call the method to start the operation for a split screen game.
                StartSplitScreenSessionOperation(e.PlayerIndex);

            };

            // Activate the ProfileSignInScreen.
            ScreenManager.AddScreen(profileSignIn, e.PlayerIndex);
    
        } // End of the SplitScreenMenuEntrySelected method

        /// <summary>
        /// Begin to start a split screen game.
        /// </summary>
        /// <param name="playerIndex"></param>
        void StartSplitScreenSessionOperation(PlayerIndex playerIndex)
        {
            // Set the maximum number of local gamers.
            NetworkSessionComponent.MaxLocalGamers = 4;

            try
            {
                // Which local profiles should we include in this session?
                IEnumerable<SignedInGamer> localGamers =
                        NetworkSessionComponent.ChooseGamers(NetworkSessionType.Local, playerIndex);

                // Begin an asynchronous create network session operation.
                IAsyncResult asyncResult = NetworkSession.BeginCreate(
                                                    NetworkSessionType.Local, localGamers,
                                                    NetworkSessionComponent.MaxGamers,
                                                    0, null, null, null);

                // Activate the network busy screen, which will display
                // an animation until this operation has completed.
                NetworkBusyScreen busyScreen = new NetworkBusyScreen(asyncResult);

                busyScreen.OperationCompleted += SplitScreenSessionOperationCompleted;

                ScreenManager.AddScreen(busyScreen, playerIndex);
            }
            catch (Exception exception)
            {
                NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception);

                ScreenManager.AddScreen(errorScreen, playerIndex);
            }

        } // End of the StartSplitScreenSessionOperation method

        /// <summary>
        /// Event handler for when the asynchronous create network session
        /// operation has completed.
        /// </summary>
        void SplitScreenSessionOperationCompleted(object sender, OperationCompletedEventArgs e)
        {
            try
            {
                // End the asynchronous create network session operation.
                NetworkSession networkSession = NetworkSession.EndCreate(e.AsyncResult);

                // Create a component that will manage the session we just created.
                NetworkSessionComponent.Create(ScreenManager, networkSession);

                // Go to the lobby screen. We pass null as the controlling player,
                // because the lobby screen accepts input from all local players
                // who are in the session, not just a single controlling player.
                ScreenManager.AddScreen(new SplitScreenLobby(networkSession), null);
            }
            catch (Exception exception)
            {
                NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception);

                ScreenManager.AddScreen(errorScreen, ControllingPlayer);
            }

        } // End of the SplitScreenSessionOperationCompleted method.


        /// <summary>
        /// Event handler for when the Live menu entry is selected.
        /// </summary>
        void LiveMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            CreateOrFindSession(NetworkSessionType.PlayerMatch, e.PlayerIndex);
        }


        /// <summary>
        /// Event handler for when the System Link menu entry is selected.
        /// </summary>
        void SystemLinkMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            CreateOrFindSession(NetworkSessionType.SystemLink, e.PlayerIndex);
        }

        /// <summary>
        /// Event handler for when the Options menu entry is selected.
        /// </summary>
        void OptionsMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            // Add the options screen.
            ScreenManager.AddScreen(new OptionScreen(), e.PlayerIndex);
        }


        /// <summary>
        /// Helper method shared by the Live and System Link menu event handlers.
        /// </summary>
        void CreateOrFindSession(NetworkSessionType sessionType,
                                 PlayerIndex playerIndex)
        {
            // First, we need to make sure a suitable gamer profile is signed in.
            ProfileSignInScreen profileSignIn = new ProfileSignInScreen(sessionType);

            // Hook up an event so once the ProfileSignInScreen is happy,
            // it will activate the CreateOrFindSessionScreen.
            profileSignIn.ProfileSignedIn += delegate
            {
                GameScreen createOrFind = new CreateOrFindSessionScreen(sessionType);

                ScreenManager.AddScreen(createOrFind, playerIndex);
            };

            // Activate the ProfileSignInScreen.
            ScreenManager.AddScreen(profileSignIn, playerIndex);
        }

        /// <summary>
        /// When the user cancels the main menu, ask if they want to exit the sample.
        /// </summary>
        protected override void OnCancel(PlayerIndex playerIndex)
        {
            MessageBoxScreen confirmExitMessageBox =
                                    new MessageBoxScreen(Resources.ConfirmExitSample);

            confirmExitMessageBox.Accepted += ConfirmExitMessageBoxAccepted;

            ScreenManager.AddScreen(confirmExitMessageBox, playerIndex);
        }

        /// <summary>
        /// Event handler for when the user selects ok on the "are you sure
        /// you want to exit" message box.
        /// </summary>
        void ConfirmExitMessageBoxAccepted(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Game.Exit();
        }

        /// <summary>
        /// Event handler to show the marketplace.
        /// </summary>
        void ShowMarketPlace(object sender, PlayerIndexEventArgs e)
        {
            // Create a message box screens.
            MessageBoxScreen confirmSignIn = new MessageBoxScreen(Resources.ConfirmSignIn);

            // Show the market place if the gamer are signed in with an online gamer profile.
            if (ProfileSignInScreen.CanPlayerBuyGame(e.PlayerIndex))
            {
                Guide.ShowMarketplace(e.PlayerIndex);
            }
            else
            {
                confirmSignIn.Accepted += delegate
                {
                    Guide.ShowSignIn(1, true);
                };

                ScreenManager.AddScreen(confirmSignIn, e.PlayerIndex);  
            }
        }

        #endregion

    } // End of the class

} // End of namespace
