using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#if WINDOWS || LINUX || ANDROID
using Microsoft.Xna.Framework.Storage;
#elif WINDOWS_PHONE
using System.IO.IsolatedStorage;
#endif
using System.IO;
using System.Text;

namespace ShootingHero
{
	public class ShootingHero : Microsoft.Xna.Framework.Game
	{
		GraphicsDeviceManager graphics;
		SpriteBatch spriteBatch;
		Random random;

#if LINUX
		bool hasChangeResolution = false;
#endif

		bool soundState = true, vibrateState = true;

		public Random Random { get { return random; } }
		public SpriteBatch SpriteBatch { get { return spriteBatch; } }

		public bool SoundState { get { return soundState; } set { soundState = value; } }
		public bool VibrateState { get { return vibrateState; } set { vibrateState = value; } }

		public ShootingHero ()
		{
			random = new Random ( Environment.TickCount );
			graphics = new GraphicsDeviceManager ( this );
			graphics.PreferredBackBufferWidth = 480;
			graphics.PreferredBackBufferHeight = 800;

			IsFixedTimeStep = true;
#if WINDOWS || LINUX
			TargetElapsedTime = TimeSpan.FromTicks ( 166666 );
#else
			TargetElapsedTime = TimeSpan.FromTicks ( 333333 );
			InactiveSleepTime = TimeSpan.FromSeconds ( 1 );

#if WINDOWS_PHONE || ANDROID
			graphics.IsFullScreen = true;
#endif
#endif

			LoadOptionData ();

			Content.RootDirectory = "Content";
		}

		protected override void Initialize ()
		{
			// TODO: Add your initialization logic here
			Components.Add ( new Transitor ( this ) );
			Components.Add ( new FrameCalculator ( this ) );

#if WINDOWS || LINUX
			this.IsMouseVisible = true;
			Window.Title = "Shooting Hero";
#endif

			base.Initialize ();
		}

		protected override void LoadContent ()
		{
			spriteBatch = new SpriteBatch ( GraphicsDevice );
		}

		protected override void Draw ( GameTime gameTime )
		{
			GraphicsDevice.Clear ( Color.Black );

#if LINUX
			if ( !hasChangeResolution )
			{
				graphics.PreferredBackBufferWidth = 480;
				graphics.PreferredBackBufferHeight = 800;
				graphics.ApplyChanges ();
				hasChangeResolution = true;
			}
#endif

			base.Draw ( gameTime );
		}

		public void LoadOptionData ()
		{
#if WINDOWS || LINUX || ANDROID
			StorageDevice.BeginShowSelector ( ( IAsyncResult ar ) =>
				{
					StorageDevice storageDevice = StorageDevice.EndShowSelector ( ar );
					storageDevice.BeginOpenContainer ( "Shooting Hero",
						( IAsyncResult ar2 ) =>
						{
							StorageContainer storageContainer = storageDevice.EndOpenContainer ( ar2 );
#endif
							Stream stream =
#if WINDOWS || LINUX || ANDROID
								storageContainer.OpenFile ( "option.bin", FileMode.OpenOrCreate, FileAccess.Read );
#elif WINDOWS_PHONE
								new IsolatedStorageFileStream ( "option.bin", FileMode.OpenOrCreate, IsolatedStorageFile.GetUserStoreForApplication () );
#endif
							if ( stream.Position != stream.Length )
							{
								BinaryReader br = new BinaryReader ( stream, Encoding.UTF8 );
								soundState = br.ReadBoolean ();
								vibrateState = br.ReadBoolean ();
							}
							stream.Close ();
#if WINDOWS || LINUX || ANDROID
						}, null );
				}, null );
#endif
		}

		public void SaveOptionData ()
		{
#if WINDOWS || LINUX || ANDROID
			StorageDevice.BeginShowSelector ( PlayerIndex.One,
				( IAsyncResult ar ) =>
				{
					StorageDevice storageDevice = StorageDevice.EndShowSelector ( ar );
					storageDevice.BeginOpenContainer ( "Shooting Hero",
						( IAsyncResult ar2 ) =>
						{
							StorageContainer storageContainer = storageDevice.EndOpenContainer ( ar2 );
#endif
							Stream stream = 
#if WINDOWS || LINUX || ANDROID
								storageContainer.OpenFile ( "option.bin", FileMode.Create, FileAccess.Write );
#elif WINDOWS_PHONE
								new IsolatedStorageFileStream ( "option.bin", FileMode.OpenOrCreate, IsolatedStorageFile.GetUserStoreForApplication () );
#endif
							if ( stream.Position != stream.Length )
							{
								BinaryWriter bw = new BinaryWriter ( stream, Encoding.UTF8 );
								bw.Write ( soundState );
								bw.Write ( vibrateState );
							}
							stream.Close ();
#if WINDOWS || LINUX || ANDROID
						}, null );
				}, null );
#endif
		}
	}
}
