using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace Sample11_Playing_Of_Encrypted_FLV_SWF
{
    public partial class Form1 : Form
    {
        string EncryptedFLVPath;
        string EncryptedSWFPath;

        enum FlashFileType { SWF, FLV };

        FlashFileType FlashType;

        public Form1()
        {
            InitializeComponent();
        }

        private void buttonEncryptFLV_Click(object sender, EventArgs e)
        {
            if (openFileDialogFLV.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                System.IO.Stream InputStream = System.IO.File.OpenRead(openFileDialogFLV.FileName);

                saveFileDialogEncyptedFLV.FileName = openFileDialogFLV.FileName + ".eflv";

                if (saveFileDialogEncyptedFLV.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    System.IO.Stream EncryptedStream = System.IO.File.Create(saveFileDialogEncyptedFLV.FileName);

                    const int nSize = 64 * 1024;
                    byte[] buffer = new byte[nSize];

                    int nReadBytes;

                    while (true)
                    {
                        nReadBytes = InputStream.Read(buffer, 0, nSize);

                        // Simple decryption
                        for (int i = 0; i < nSize; i++)
                        {
                            buffer[i] ^= 0x35;
                        }

                        if (0 == nReadBytes)
                            break;

                        EncryptedStream.Write(buffer, 0, nReadBytes);
                    }

                    EncryptedStream.Close();
                }

                InputStream.Close();

                if (MessageBox.Show("Would like to play the encrypted FLV?", "Question", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
                {
                    EncryptedFLVPath = saveFileDialogEncyptedFLV.FileName;
                    PlayFLV("flv", "http://FLV/FlashVideo.flv");
                }
            }
        }

        private void ButtonPlayFLV_Click(object sender, EventArgs e)
        {
            if (openFileDialogEncyptedFLV.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                EncryptedFLVPath = openFileDialogEncyptedFLV.FileName;
                PlayFLV("flv", "http://FLV/FlashVideo.flv");
            }
        }

        private void buttonPlay_Click(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.SWF)
            {
                f_in_box__control1.FlashMethod_Play();
            }
            else
            {
                f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"resumeVideo\" returntype=\"void\"><arguments></arguments></invoke>");
            }
        }

        private void buttonPause_Click(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.SWF)
            {
                f_in_box__control1.FlashMethod_Stop();
            }
            else
            {
                f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"pauseVideo\" returntype=\"void\"><arguments></arguments></invoke>");
            }
        }

        private float GetCurrentVideoPosition()
        {
            string strXMLPosition = f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"getCurrPosition\" returntype=\"xml\"><arguments></arguments></invoke>");
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(strXMLPosition);
            System.Globalization.NumberFormatInfo NumberFormatInfo = new System.Globalization.NumberFormatInfo();
            NumberFormatInfo.NumberDecimalSeparator = ".";
            return float.Parse(doc.DocumentElement.InnerText, NumberFormatInfo);
        }

        private void buttonBack_Click(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.SWF)
            {
                f_in_box__control1.FlashMethod_Back();
            }
            else
            {
                float NewCurrentPosition = GetCurrentVideoPosition() - 5;

                if (NewCurrentPosition < 0)
                    NewCurrentPosition = 0;

                f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"seekVideo\" returntype=\"xml\"><arguments><number>" + ((int)NewCurrentPosition).ToString() + "</number></arguments></invoke>");
            }
        }

        private void buttonForward_Click(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.SWF)
            {
                f_in_box__control1.FlashMethod_Forward();
            }
            else
            {
                float NewCurrentPosition = GetCurrentVideoPosition() + 5;

                f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"seekVideo\" returntype=\"xml\"><arguments><number>" + ((int)NewCurrentPosition).ToString() + "</number></arguments></invoke>");
            }
        }

        private void checkBoxShowControls_CheckedChanged(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.FLV)
            {
                if (checkBoxShowControls.Checked)
                    f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"showAllControl\" returntype=\"void\"><arguments></arguments></invoke>");
                else
                    f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"hideAllControl\" returntype=\"void\"><arguments></arguments></invoke>");
            }
        }

        private void ButtonAbout_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.f-in-box.com/dotnet/");
        }

        private void ButtonOrder_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.f-in-box.com/dotnet/order.html");
        }

        private void CheckBoxEnableSounds_CheckedChanged(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.FLV)
            {
                f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"setMute\" returntype=\"xml\"><arguments>" + (CheckBoxEnableSounds.Checked ? "<false />" : "<true />") + "</arguments></invoke>");

                if (CheckBoxEnableSounds.Checked)
                    labelSoundVolume.Text = trackBarSoundVolume.Value.ToString() + " %";
                else
                    labelSoundVolume.Text = "Disabled";

                trackBarSoundVolume.Enabled = CheckBoxEnableSounds.Checked;
            }
        }

        private void trackBarSoundVolume_Scroll(object sender, EventArgs e)
        {
            if (FlashType == FlashFileType.FLV)
            {
                f_in_box__control1.FlashMethod_CallFunction("<invoke name=\"setVolume\" returntype=\"xml\"><arguments><number>" + trackBarSoundVolume.Value.ToString() + "</number></arguments></invoke>");

                labelSoundVolume.Text = trackBarSoundVolume.Value.ToString() + " %";
            }
        }

        private void PlayFLV(string TypeVideo, string URL)
        {
            FlashType = FlashFileType.FLV;

            f_in_box__control1.FlashProperty_FlashVars = BuildFlashVars(TypeVideo, URL, !CheckBoxEnableSounds.Checked, trackBarSoundVolume.Value, checkBoxPlayAutomatically.Checked, checkBoxShowControls.Checked);
            f_in_box__control1.PutMovieFromStream(this.GetType().Assembly.GetManifestResourceStream("Sample11_Playing_Of_Encrypted_FLV_SWF.res.FlashVideoPlayer.swf"));
        }

        private void PlaySWF(string URL)
        {
            FlashType = FlashFileType.SWF;

            f_in_box__control1.FlashMethod_LoadMovie(0, URL);
        }

        private static string BuildFlashVars(string TypeVideo, string URL, bool Mute, int AudioVolume, bool AutoPlay, bool ShowControls)
        {
            string strFlashVars = "type_video=" + TypeVideo;

            strFlashVars += "&url=" + System.Web.HttpUtility.HtmlEncode(URL);

            strFlashVars += "&auto_play=" + (AutoPlay ? "true" : "false");

            // Specify mute=1 to disable audio, don't specify mute at all to enable audio
            if (Mute) strFlashVars += "&mute=1";

            strFlashVars = strFlashVars + "&volume=" + AudioVolume.ToString();

            strFlashVars += "&auto_play=" + (AutoPlay ? "true" : "false");
            strFlashVars += "&hide_control=" + (ShowControls ? "false" : "true");

            return strFlashVars;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            f_in_box__control1.AxCode.OnLoadExternalResourceByFullPath += OnLoadExternalResourceByFullPath;

            openFileDialogFLV.InitialDirectory = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

            PlayFLV("flv", "");

            f_in_box__control1.FlashProperty_AllowFullscreen = true;
        }

		private void OnLoadExternalResourceByFullPath(object sender, String URL, System.IO.Stream Stream, ref bool Handled)
		{
			if (URL == "http://FLV/FlashVideo.flv")
			{
                System.IO.Stream EncryptedFLVStream = System.IO.File.OpenRead(EncryptedFLVPath);

                DecryptStreamAndWriteToStream DecryptStreamAndWriteToStream = new DecryptStreamAndWriteToStream(EncryptedFLVStream, Stream);

                Handled = true;
			}
            else if (URL == "http://SWF/FlashFile.swf")
            {
                System.IO.Stream EncryptedSWFStream = System.IO.File.OpenRead(EncryptedSWFPath);

                DecryptStreamAndWriteToStream DecryptStreamAndWriteToStream = new DecryptStreamAndWriteToStream(EncryptedSWFStream, Stream);

                Handled = true;
            }
		}

        private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (FlashType == FlashFileType.FLV)
            { 
                float Position = GetCurrentVideoPosition();

                if (-1 != Position)
                {
                    trackBarVideoPosition.Value = (int)Position;
                    LabelInfo.Text = "Current time: " + ((int)Position).ToString() + " s " + ((int)((Position - (int)Position) * 100)).ToString() + " ms";
                }
            }
        }

        private void buttonEncryptSWF_Click(object sender, EventArgs e)
        {
            if (openFileDialogSWF.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                System.IO.Stream InputStream = System.IO.File.OpenRead(openFileDialogSWF.FileName);

                saveFileDialogEncyptedSWF.FileName = openFileDialogSWF.FileName + ".eswf";

                if (saveFileDialogEncyptedSWF.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    System.IO.Stream EncryptedStream = System.IO.File.Create(saveFileDialogEncyptedSWF.FileName);

                    const int nSize = 64 * 1024;
                    byte[] buffer = new byte[nSize];

                    int nReadBytes;

                    while (true)
                    {
                        nReadBytes = InputStream.Read(buffer, 0, nSize);

                        // Simple decryption
                        for (int i = 0; i < nSize; i++)
                        {
                            buffer[i] ^= 0x35;
                        }

                        if (0 == nReadBytes)
                            break;

                        EncryptedStream.Write(buffer, 0, nReadBytes);
                    }

                    EncryptedStream.Close();
                }

                InputStream.Close();

                if (MessageBox.Show("Would like to play the encrypted SWF?", "Question", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
                {
                    EncryptedSWFPath = saveFileDialogEncyptedSWF.FileName;
                    PlaySWF("http://SWF/FlashFile.swf");
                }
            }
        }

        private void ButtonPlaySWF_Click(object sender, EventArgs e)
        {
            if (openFileDialogEncyptedSWF.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                EncryptedSWFPath = openFileDialogEncyptedSWF.FileName;
                PlaySWF("http://SWF/FlashFile.swf");
            }
        }
    }
 
    class DecryptStreamAndWriteToStream
    {
        private System.IO.Stream EncryptedStream;
        private System.IO.Stream OutputStream;
        private System.Threading.Thread Thread;

        public DecryptStreamAndWriteToStream(System.IO.Stream EncryptedStream, System.IO.Stream OutputStream)
        {
            this.EncryptedStream = EncryptedStream;
            this.OutputStream = OutputStream;

            Thread = new System.Threading.Thread(new System.Threading.ThreadStart(Main));

            Thread.Start();
        }

        private void Main()
        {
            const int nSize = 64 * 1024;
            byte[] buffer = new byte[nSize];

            while (true)
            {
                int nReadBytes = EncryptedStream.Read(buffer, 0, nSize);

                // Simple decryption
                for (int i = 0; i < nSize; i++)
                {
                    buffer[i] ^= 0x35;
                }

                if (0 == nReadBytes)
                    break;

                try
                {
                    OutputStream.Write(buffer, 0, nReadBytes);
                }
                catch (System.IO.IOException)
                {
                    // Loading is interrupted
                    break;
                }
            }

            EncryptedStream.Close();
            OutputStream.Close();
        }
    }
}