using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace GestoreTrimestrale.Logic
{
    public class PdfManagerProcess : IDisposable
    {        


        public int MaxProcessiGestorePDF { get; private set; }  //desired number of concurrent processes running
        public int ProcessiGestorePDF { get { return PDFWorkers.Count(); } } //current number of running processes
        public ManagerProcessStatusEnum Status { get; set; } //process status         

        //public string PathProcesso { get; private set; } //path to .exe file
        //public List<Process> ActiveProcesses { get; private set; } //list of active processes
        private List<BackgroundWorker> pdfWorkers { get; set; } //our thread to process zipping

        //will be used for the main controller to handling "process completed" event (enabling textboxes)
        public List<BackgroundWorker> PDFWorkers
        {
            get
            {
                return pdfWorkers;
            }
            set
            {
                pdfWorkers = value;
            }

        }

        public PdfManagerProcess() //path to .exe string pathProcesso
        {
            Status = ManagerProcessStatusEnum.Pending;
            PDFWorkers = new List<BackgroundWorker>();
            //ActiveProcesses = new List<Process>();
            //PathProcesso = pathProcesso;
        }        

        //if current number of active processes is lower than desired, add new processes
        public int IncreaseNumberOfProcess(int desiredTotalNumberOfProcesses)
        {
            if (desiredTotalNumberOfProcesses <= ProcessiGestorePDF) return -1; //desired number is lower than current - this is an error
            return UpdateProcessing(desiredTotalNumberOfProcesses); //add new processes
        }

        //start processing with provided number of concurrent processes
        public int StartProcessing(int maxProcessiGestorePDF)
        {
            return UpdateProcessing(maxProcessiGestorePDF);
        }

        //will kill all existing processes.... a terrible thing
        //this will not wait until process ends... it will just send the termination signal
        public void Dispose()
        {
            //foreach (Process p in ActiveProcesses)
                //p.Close();
            foreach (BackgroundWorker w in PDFWorkers)
                w.CancelAsync();
        }
        
        //start a new process and returns it 
        //private Process CreateProcess(string pathProcesso)
        //{
            //return Process.Start(PathProcesso);
        //}

        private BackgroundWorker CreateWorker()
        {
            Status = ManagerProcessStatusEnum.Processing;
            BackgroundWorker backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += backgroundWorker_DoWork;
            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
            backgroundWorker.RunWorkerAsync();
            return backgroundWorker;
        }

        void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
             PDFWorkers.Remove((BackgroundWorker)sender);
            if (pdfWorkers.Count == 0)
                Status = ManagerProcessStatusEnum.Completed;
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                GestorePDF.Logic.ThreadManager m = new GestorePDF.Logic.ThreadManager();
                m.Main();
            }
            catch (Exception ex)
            {
                string s = ex.Message;
            }
        }


        //create additional processes if neccesary to reach the maxProcessiGestorePDF
        private int UpdateProcessing(int maxProcessiGestorePDF)
        {
            int current = ProcessiGestorePDF;
            if (maxProcessiGestorePDF == current) return 0; //we're fine
            if (maxProcessiGestorePDF < current) return -1; //error, it's a shame we are not handling process termination here
            int createdProcesses = maxProcessiGestorePDF - current; //number of processes to create
            for (int i = 0; i < createdProcesses; i++) //i know using loop is bad
            {
                //ActiveProcesses.Add(CreateProcess(PathProcesso)); //add new process to the list. this will also update ProcessiGestorePDF
                PDFWorkers.Add(CreateWorker());
            }
            return createdProcesses; //returns the number of processes created
        }      
        
    }
}