using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
using System.Diagnostics;
using System.IO;

namespace barry
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Methods methods = new Methods();

        internal BackupConfig bkp;

        public MainWindow()
        {
            InitializeComponent();
            //connect_console_to_textbox();
            displays_barry_picture();

            lbl_cpuname.Content = methods.computer_name();
            lbl_driveletter.Content = methods.current_drive_label() + " (" + methods.current_drive_letter() + ")";
            lbl_cpu_uuid.Content = methods.get_machine_guid();
            
            print("**** BARRY Backup ****");

            try
            {
                bkp = methods.load_this_cpu();
            }
            catch (DirectoryNotFoundException e)
            {
                bkp = null;
                MessageBox.Show("Error while loading the backup: " + e.Data);
            }

            if (bkp == null)
            {
                print(">> unknown machine");
                btn_backup.IsEnabled = false;
                btn_preview.IsEnabled = false;
                return;
            }

            print("Source: " + bkp_source());
            print("Target of the backup: " + bkp_target());
            
        }

        internal string bkp_source()
        {
            return bkp.dir_path;
        }

        internal string bkp_target()
        {
            return methods.current_drive_letter() + bkp.local_subdir;
        }

        private void displays_barry_picture()
        {
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri("O:\\dev\\barry\\barry\\barrys_head.png");
            bitmap.EndInit();
            img_barry.Source = bitmap;
        }

        private string last_added = "";
        public void print(string line, bool flush = false)
        {
            txt_console.AppendText(line + "\n");
            txt_console.ScrollToEnd();
            last_added = line + "\n";
        }

        /// <summary>
        /// this void runs immediatly after the main window loaded
        /// </summary>
        private void autoexec()
        {
            //System.Threading.Thread.Sleep(7000);
            //methods.cmd(String.Format("ROBOCOPY {0} {1} /E /XO /w:1 /r:3 /L", source, target));

            // /E : recursive
            // /XO : only copy newer files
            // /w:1 /r:3 : if fails, retry 3 times waiting 1 sec each time
            // /L : only list the ongoing copy, do not proceed
        }

        private void OnWindowLoaded(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(new Action(() => autoexec()), DispatcherPriority.ContextIdle, null);
        }


        private void btn_backup_Click(object sender, RoutedEventArgs e)
        {
            cmd(String.Format("ROBOCOPY {0} {1} /E /XO /w:1 /r:3", bkp_source(), bkp_target()));
        }

        private void btn_preview_Click(object sender, RoutedEventArgs e)
        {
            cmd(String.Format("ROBOCOPY {0} {1} /E /XO /L", bkp_source(), bkp_target()));
        }

        public void cmd(string cmd)
        {
            using (System.Diagnostics.Process p = new System.Diagnostics.Process())
            {
                print(">> " + cmd);

                p.StartInfo.FileName = "CMD.EXE";
                p.StartInfo.Arguments = String.Format("/C {0}", cmd);

                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                //p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
                //p.StartInfo.RedirectStandardInput = true;

                p.StartInfo.RedirectStandardError = true;
                //p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
                p.StartInfo.CreateNoWindow = true;
                p.OutputDataReceived += new DataReceivedEventHandler(process_ouput_handler);
                //p.ErrorDataReceived += new DataReceivedEventHandler(process_error_handler);

                p.Start();
                p.BeginOutputReadLine();

            }

        }

        private void process_ouput_handler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            Dispatcher.BeginInvoke(new Action(() => print(outLine.Data)), DispatcherPriority.ContextIdle, null);
        }

        private void process_error_handler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            Dispatcher.BeginInvoke(new Action(() => print(outLine.Data)), DispatcherPriority.ContextIdle, null);
        }

        private void btn_options_Click(object sender, RoutedEventArgs e)
        {
            if (bkp == null)
            {
                string msg = "Barry do not know this computer, do you want him to memorize it?";
                MessageBoxResult result = MessageBox.Show(msg, "Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.No)
                {
                    return;
                }
                methods.register_this_cpu();
                bkp = methods.load_this_cpu();

            }

            Window opt_window = new OptionsWindow(bkp);
            opt_window.Owner = this;
            opt_window.ShowDialog();


        }

    }



}

// *** BACKUP
// 1- read the configuration file
// IF NOT: warn, and create an empty, then quit
// IF INVALID: warn and quit


// 2- control media name to see if good source 
//    OR check existnce of a file which is nor copied 
//    OR mark the destination directory as a backup dir and warn before being launbching from there
// IF NOT: quit

// 3- check the computer name (or mac adress?) >> UUID
// if not found in cpu list: quit

// 4- get the map letter and expand source

// 5- get the destination path in config file
// expands it
// if none|inexistent|unauthorized, warn and displays a selection dialog
// if cancelled, cancel prog and quit

// 6- Displays the ongoing copy operation with source and destination

// ***** to replace robocopy?
// opt- analyse the source and destination:
// build a tree of files
// if source file do not exist in destination: copy
// if source file is older than destination, replace it

// #renamed file case:
// if 2 files have same signature but differents names, propose to rename
// #renamed dir case
// 
// #moved file case
//
// #moved dir case
//
// ****

// 8- Waits 14 seconds and propose a key to cancel

// 9- process to copy

// 10- displays results

// END OF BACKUP

// other tools:
// purge backup: propose to remove or trash destination files which do not exist anymore in source
// add this computer: add a computer in the list of backup targets
// enable autorun: copy usbAR on the post, configure and run