/* This file is part of AHD Subtitles Maker Professional
   A program can create and edit subtitles

   Copyright © Ala I Hadid 2009 - 2012

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using System.Resources;
using AHD.SM.ASMP;
namespace AHD.SM.Controls
{
    public partial class MediaPlayer : UserControl
    {
        ResourceManager resources = new ResourceManager("AHD.SM.Controls.LanguageResources.Resource",
            Assembly.GetExecutingAssembly());
        public MediaPlayer()
        {
            InitializeComponent();
            axWindowsMediaPlayer1.PlayStateChange += new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(axWindowsMediaPlayer1_PlayStateChange);
            nextTimer = new Timer();
            prevTimer = new Timer();
            nextTimer.Interval = prevTimer.Interval = 100;
            nextTimer.Tick += new EventHandler(nextTimer_Tick);
            prevTimer.Tick += new EventHandler(prevTimer_Tick);
        }
        void nextTimer_Tick(object sender, EventArgs e)
        {
            NextFrame();
        }
        void prevTimer_Tick(object sender, EventArgs e)
        {
            PreviousFrame();
        }

        //play state change
        void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
        {
            if ((axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsPaused) |
                (axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsStopped))
            {
                Button_playPause.Image = Properties.Resources.Play;
            }
            if ((axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsPlaying))
            {
                Button_playPause.Image = Properties.Resources.pause2;
            }
        }
        double mediaDuration = 0;
        bool isScrolling = false;
        double advanceTime = 0.500;
        Timer nextTimer = new Timer();
        Timer prevTimer = new Timer();

        /// <summary>
        /// Open a media file
        /// </summary>
        /// <param name="FilePath">The complete path of the media file</param>
        public void LoadMedia(string FilePath)
        {
            axWindowsMediaPlayer1.Ctlcontrols.stop();
            axWindowsMediaPlayer1.currentPlaylist.clear();
            axWindowsMediaPlayer1.URL = null;
            if (File.Exists(FilePath))
            {
                WMPLib.IWMPMedia m1 = axWindowsMediaPlayer1.newMedia(FilePath);
                mediaDuration = m1.duration;
                axWindowsMediaPlayer1.currentPlaylist.appendItem(m1);
            }
        }
        /// <summary>
        /// Stop and remove the media form the player
        /// </summary>
        public void ClearMedia()
        {
            axWindowsMediaPlayer1.Ctlcontrols.stop();
            axWindowsMediaPlayer1.currentPlaylist.clear();
            axWindowsMediaPlayer1.URL = null;
        }
        public void TogglePlayPause()
        {
            if (IsPlaying)
                Pause();
            else
                Play();
        }
        /// <summary>
        /// Play or resume
        /// </summary>
        public void Play()
        {
            if (axWindowsMediaPlayer1.currentPlaylist.count == 0)
            {
                if (ChangeMediaRequest != null)
                    ChangeMediaRequest(this, null);
            }
            axWindowsMediaPlayer1.Ctlcontrols.play();
        }
        /// <summary>
        /// Pause
        /// </summary>
        public void Pause()
        {
            axWindowsMediaPlayer1.Ctlcontrols.pause();
        }
        /// <summary>
        /// Stop
        /// </summary>
        public void Stop()
        {
            axWindowsMediaPlayer1.Ctlcontrols.stop();
        }
        public void ToggleMute()
        {
            axWindowsMediaPlayer1.settings.mute = !axWindowsMediaPlayer1.settings.mute;
            toolStripButton_mute.Image = axWindowsMediaPlayer1.settings.mute ? Properties.Resources.Mute : Properties.Resources.sound;
            toolStripButton_mute.ToolTipText = axWindowsMediaPlayer1.settings.mute ? resources.GetString("SoundOff") :
                resources.GetString("SoundOn");
            if (MuteToggle != null)
                MuteToggle(this, new EventArgs());
        }
        /// <summary>
        /// Get if the player is playing or not
        /// </summary>
        public bool IsPlaying
        {
            get
            {
                if (axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsPlaying)
                { return true; }
                else { return false; }
            }
        }
        /// <summary>
        /// Update controls and scroll bar
        /// </summary>
        public void UpdateTimer()
        {
            if (axWindowsMediaPlayer1.currentMedia != null)
            {
                trackBar_time.Enabled = (axWindowsMediaPlayer1.currentMedia.duration > 0);
                trackBar_time.Maximum = (int)(axWindowsMediaPlayer1.currentMedia.duration * 1000);
                if ((axWindowsMediaPlayer1.Ctlcontrols.currentPosition * 1000) < trackBar_time.Maximum
                    && !isScrolling)
                    trackBar_time.Value = (int)(axWindowsMediaPlayer1.Ctlcontrols.currentPosition * 1000);

                label_currentTime.Text = TimeFormatConvertor.To_TimeSpan_Milli(axWindowsMediaPlayer1.Ctlcontrols.currentPosition);
                label_duration.Text = TimeFormatConvertor.To_TimeSpan_Milli(axWindowsMediaPlayer1.currentMedia.duration);
            }
            else
            {
                trackBar_time.Enabled = false;
            }
        }
        /// <summary>
        /// Show the subtitle to the user
        /// </summary>
        /// <param name="text">The subtitle text you want to show</param>
        public void ShowSubtitle(SubtitleText text)
        {
            //show and hide
            if (subtitleTextEditor1.Visible)
                subtitleTextEditor1.Visible = false;
            subtitleTextEditor1.SubtitleText = text;

            subtitleTextViewer1.ViewText(text);
            //size
            Size textSize = SubtitleTextWrapper.GetSize(text);
            int w = textSize.Width;
            int h = textSize.Height;
            subtitleTextViewer1.Size = new Size(w, h);
            //location
            if (text.IsCustomPosition)
            {
                subtitleTextViewer1.Location = text.CustomPosition;
            }
            else
            {
                int NewWidth = 0;
                int NewHeight = 0;
                switch (text.Position)
                {
                    case SubtitlePosition.Down_Middle:
                        NewWidth = (this.Size.Width / 2) - (subtitleTextViewer1.Size.Width / 2);
                        NewHeight = this.Size.Height - (75 + subtitleTextViewer1.Height);
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                    case SubtitlePosition.Down_Left:
                        NewWidth = 5;
                        NewHeight = this.Size.Height - (75 + subtitleTextViewer1.Height);
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                    case SubtitlePosition.Down_Right:
                        NewWidth = this.Width - (subtitleTextViewer1.Size.Width + 5);
                        NewHeight = this.Size.Height - (75 + subtitleTextViewer1.Height);
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;

                    case SubtitlePosition.Mid_Middle:
                        NewWidth = (this.Size.Width / 2) - (subtitleTextViewer1.Size.Width / 2);
                        NewHeight = (this.Size.Height / 2) - (subtitleTextViewer1.Size.Height / 2);
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                    case SubtitlePosition.Mid_Left:
                        NewWidth = 5;
                        NewHeight = (this.Size.Height / 2) - (subtitleTextViewer1.Size.Height / 2);
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                    case SubtitlePosition.Mid_Right:
                        NewWidth = this.Width - (subtitleTextViewer1.Size.Width + 5);
                        NewHeight = (this.Size.Height / 2) - (subtitleTextViewer1.Size.Height / 2);
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;

                    case SubtitlePosition.Top_Middle:
                        NewWidth = (this.Size.Width / 2) - (subtitleTextViewer1.Size.Width / 2);
                        NewHeight = 5;
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                    case SubtitlePosition.Top_Left:
                        NewWidth = 5;
                        NewHeight = 5;
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                    case SubtitlePosition.Top_right:
                        NewWidth = this.Width - (subtitleTextViewer1.Size.Width + 5);
                        NewHeight = 5;
                        subtitleTextViewer1.Location = new Point(NewWidth, NewHeight);
                        break;
                }
            }
            subtitleTextViewer1.Visible = true;
        }
        /// <summary>
        /// Hide the subtitle
        /// </summary>
        public void HideSubtitle()
        {
            subtitleTextViewer1.HideText();
            subtitleTextEditor1.Visible = subtitleTextViewer1.Visible = false;
        }
        public void SetInfoTextOfAddButton(string text)
        {
            label_info.Visible = (text != "");
            label_info.Text = text;
        }

        public void NextFrame()
        {
            try
            {
                axWindowsMediaPlayer1.Ctlcontrols.currentPosition += advanceTime;
            }
            catch { }
        }
        public void PreviousFrame()
        {
            try
            {
                axWindowsMediaPlayer1.Ctlcontrols.currentPosition -= advanceTime;
            }
            catch { }
        }
        //Properties
        /// <summary>
        /// Get or set current position of the player
        /// </summary>
        public double CurrentPosition
        {
            get { return axWindowsMediaPlayer1.Ctlcontrols.currentPosition; }
            set { try { axWindowsMediaPlayer1.Ctlcontrols.currentPosition = value; } catch { } }
        }
        /// <summary>
        /// Get the current media duration
        /// </summary>
        public double Duration
        {
            get
            {
                if (axWindowsMediaPlayer1.currentMedia != null)
                    return axWindowsMediaPlayer1.currentMedia.duration;
                return 0;
            }
        }
        /// <summary>
        /// Get a string represents current duration
        /// </summary>
        public string DurationString
        {
            get
            {
                if (axWindowsMediaPlayer1.currentMedia != null)
                    return axWindowsMediaPlayer1.currentMedia.durationString;
                return "";
            }
        }
        /// <summary>
        /// Get or set the volume (0 - 100)
        /// </summary>
        public int Volume
        {
            get { return axWindowsMediaPlayer1.settings.volume; }
            set
            {
                axWindowsMediaPlayer1.settings.volume = value;
                trackBar1.Value = axWindowsMediaPlayer1.settings.volume;
                toolTip1.SetToolTip(trackBar1, resources.GetString("Volume") + ": " + trackBar1.Value + "%");
            }
        }
        /// <summary>
        /// Get or set the advance time in seconds that used in next/previous frame buttons
        /// </summary>
        public double AdvanceTime
        {
            get { return advanceTime; }
            set
            {
                advanceTime = value;
                toolStripButton2.ToolTipText = "+ " + advanceTime.ToString("F3") + " sec";
                toolStripButton1.ToolTipText = "- " + advanceTime.ToString("F3") + " sec";
            }
        }
        /// <summary>
        /// Get or set if muted
        /// </summary>
        public bool Mute
        {
            get { return axWindowsMediaPlayer1.settings.mute; }
            set
            {
                axWindowsMediaPlayer1.settings.mute = value;
                toolStripButton_mute.ToolTipText = axWindowsMediaPlayer1.settings.mute ? resources.GetString("SoundOff") :
             resources.GetString("SoundOn");
            }
        }
        /// <summary>
        /// Get or set if the add button is enabled
        /// </summary>
        public bool AddButtonEnabled
        {
            get { return AddButton.Enabled; }
            set { AddButton.Enabled = value; }
        }
        /// <summary>
        /// Get or set if the end set button is enabled
        /// </summary>
        public bool EndSetButtonEnabled
        {
            get { return EndSetButon.Enabled; }
            set { EndSetButon.Enabled = value; }
        }
        /// <summary>
        /// Get or set the back color of the subtitle textbox
        /// </summary>
        public Color EditorBackColor
        {
            get { return subtitleTextEditor1.BackColor; }
            set { subtitleTextViewer1.BackColor = subtitleTextEditor1.BackColor = value; }
        }
        public bool ShowEditorStatusStrip
        { get { return subtitleTextEditor1.ShowStatusStrip; } set { subtitleTextEditor1.ShowStatusStrip = value; } }
        //events
        public event EventHandler SaveRequest;
        /// <summary>
        /// Rised when the user starting hold the add button
        /// </summary>
        public event EventHandler AddButtonHoldPress;
        /// <summary>
        /// Rised when the user release the add button
        /// </summary>
        public event EventHandler AddButtonHoldRelease;
        /// <summary>
        /// Rised when the user clicked the end set button
        /// </summary>
        public event EventHandler EndSetButtonPressed;
        public event EventHandler MuteToggle;
        public event EventHandler TimeSlide;
        public event EventHandler ChangeMediaRequest;

        private void Button_playPause_Click(object sender, EventArgs e)
        {
            if (IsPlaying)
                Pause();
            else
                Play();
            if (TimeSlide != null)
                TimeSlide(sender, e);
        }
        //stop
        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            Stop();
        }
        private void subtitleTextEditor1_SubtitleTextChanged(object sender, EventArgs e)
        {
            if (SaveRequest != null)
                SaveRequest(sender, e);
        }
        private void toolStripButton1_MouseDown(object sender, MouseEventArgs e)
        {
            if (AddButtonHoldPress != null)
                AddButtonHoldPress(sender, e);
        }
        private void toolStripButton1_MouseUp(object sender, MouseEventArgs e)
        {
            if (AddButtonHoldRelease != null)
                AddButtonHoldRelease(sender, e);
        }
        private void toolStripButton1_MouseLeave(object sender, EventArgs e)
        {
            if (AddButtonHoldRelease != null)
                AddButtonHoldRelease(sender, e);
        }
        private void EndSetButon_Click(object sender, EventArgs e)
        {
            if (EndSetButtonPressed != null)
                EndSetButtonPressed(sender, e);
        }
        private void AddButton_EnabledChanged(object sender, EventArgs e)
        {
            if (!AddButton.Enabled)
            {
                if (AddButtonHoldRelease != null)
                    AddButtonHoldRelease(sender, e);
            }
        }
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
            toolTip1.SetToolTip(trackBar1, resources.GetString("Volume") + ": " + trackBar1.Value + "%");
        }
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            ToggleMute();
        }
        private void trackBar_time_MouseDown(object sender, MouseEventArgs e)
        {
            isScrolling = true;
        }
        private void trackBar_time_MouseUp(object sender, MouseEventArgs e)
        {
            isScrolling = false;
            axWindowsMediaPlayer1.Ctlcontrols.currentPosition = (double)trackBar_time.Value / 1000;
            toolTip1.SetToolTip(trackBar_time, "");
            if (TimeSlide != null)
                TimeSlide(sender, e);
        }
        private void trackBar_time_Scroll(object sender, EventArgs e)
        {
            if (isScrolling)
            {
                toolTip1.SetToolTip(trackBar_time,
                    TimeFormatConvertor.To_TimeSpan_Milli((double)trackBar_time.Value / 1000) + "\n" + (double)trackBar_time.Value / 1000);
            }
        }
        //next frame
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            NextFrame();
        }
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            PreviousFrame();
        }
        private void toolStripButton2_MouseDown(object sender, MouseEventArgs e)
        {
            nextTimer.Start();
        }
        private void toolStripButton1_MouseDown_1(object sender, MouseEventArgs e)
        {
            prevTimer.Start();
        }
        private void toolStripButton2_MouseUp(object sender, MouseEventArgs e)
        {
            nextTimer.Stop();
        }
        private void toolStripButton1_MouseUp_1(object sender, MouseEventArgs e)
        {
            prevTimer.Stop();
        }
        private void subtitleTextViewer1_EditRequest(object sender, EventArgs e)
        {
            Stop();

            subtitleTextViewer1.HideText();
            subtitleTextViewer1.Visible = false;

            subtitleTextEditor1.Visible = true;
        }
        //change subtitle's position
        private void subtitleTextEditor1_MoveButtonPressed(object sender, EventArgs e)
        {

        }
    }
}
