﻿/*
 * Project Name : Piano tiles
 * Description  : Handle every action on the game
 * School       : CFPT-i
 * Authors      : Baptiste Coudray, Sacha Leroy
 * Class        : T.IS-E2B
 * Version      : 1.0
 */
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using NAudio.Wave;

namespace PianoTiles
{
    public class PianoTile : Panel
    {
        private static readonly Point DEFAULT_LOCATION = new Point(12, 27);
        private static readonly Size DEFAULT_SIZE = new Size(492, 492);


        private List<Field> _fields;
        private List<Player> _players;

        private List<Field> Fields
        {
            get { return _fields; }
            set { _fields = value; }
        }

        private int NumberOfPlayers => this.Players.Count;

        private List<Player> Players
        {
            get { return _players; }
            set { _players = value; }
        }

        private Sound _music;
        private Sound Music
        {
            get { return _music; }
            set { _music = value; }
        }

        public PlaybackState State
        {
            get { return this.Music.State; }
        }

        public PianoTile(List<Player> players, string soundUrl)
        {
            this.Fields = new List<Field>();
            this.Players = players;
            this.Music = new Sound(soundUrl);
            for (int i = 0; i < this.Players.Count; i++)
            {
                this.Fields.Add(
                    new Field(this.Players[i], new Point(
                        Field.DEFAULT_SIZE.Width * i + 5,
                        Field.DEFAULT_SIZE.Height * i + 5
                        ), this.Music
                    )
                );
            }
            this.InitializeComponent();
            this.Music.Play();
            this.Play();
        }

        private void InitializeComponent()
        {
            this.Size = PianoTile.DEFAULT_SIZE;
            this.Location = PianoTile.DEFAULT_LOCATION;
            this.BorderStyle = BorderStyle.FixedSingle;
            this.DoubleBuffered = true;
            this.Fields.ForEach(f => this.Controls.Add(f));
        }

        public void Play()
        {
            this.Music.Play();
            this.Fields.ForEach(f => f.Play());
        }

        public void Pause()
        {
            this.Music.Pause();
            this.Fields.ForEach(f => f.Pause());
        }

        public void Stop()
        {
            this.Music.Stop();
            this.Fields.ForEach(delegate (Field field)
            {
                if (field.Status == GameStatus.Playing)
                {
                    field.Stop();
                    field.ShowEndGameMessage();
                }
                field.Save();
            });
        }

        public void MoveTiles()
        {
            if (this.Music.State == PlaybackState.Playing)
            {
                this.Fields.ForEach(f => f.MoveTiles());
                // if all fields are stopped we stop the game
                if (this.Fields.Count(f => f.Status == GameStatus.Stopped) == this.Fields.Count)
                {
                    this.Stop();
                }
            }
            else if (this.Music.State == PlaybackState.Stopped)
            {
                this.Stop();
            }
        }

        /// <summary>
        /// Free the component, the sound and the fields
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            this.Music.Dispose();
            this.Fields.ForEach(f => f.Dispose());
        }
    }
}