using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

using EQNetwork.Utility;
using EQNetwork.Aspects;

namespace EQNetwork.Objects
{
    public class UploadContext : PropertyChangeTracker
    {
        // The following fields are used by Upload_Controller to direct the upload process

        public int PreferredChunkSize = 0x1000;
        public int NumberOfChunks = 10;

        public string Name;
        public string Path;
        public long? FileSize;

        private UploadState _state;
        public UploadState State
        {
            get { return _state; }
            set 
            { 
                _state = value;
                if (EQException != null)
                    OnError(EQException);
                else if (OnStateChange != null)
                    OnStateChange(this, _state);
                _timeSinceLastStateChange = TimeSpan.FromSeconds(0);
            }
        }
        public enum UploadState
        {
            Unknown,
            START,
            GET_FILE_DATA,
            GET_FILE_DATA_PENDING,
            BEGIN,
            BEGIN_PENDING,
            DOWNLOAD_CHUNKLIST,
            DOWNLOAD_CHUNKLIST_PENDING,
            UPLOAD_CHUNKS,
            COMPLETE,
            COMPLETE_PENDING,
            CREATE_CONTENTFILE,
            CREATE_CONTENTFILE_PENDING,
            WAITING_FOR_ALL_TO_SEE_DELAY,
            WAITING_FOR_ALL_TO_SEE,
            WAITING_FOR_ALL_TO_SEE_PENDING,
            FINISHED,
            CANCELLED,
        }

        private TimeSpan _timeSinceLastStateChange = TimeSpan.MaxValue;

        public void PumpTimeSinceLastStateChange(TimeSpan duration)
        {
            if (_timeSinceLastStateChange == TimeSpan.MaxValue)
                _timeSinceLastStateChange = duration;
            else
                _timeSinceLastStateChange += duration;
        }

        public TimeSpan TimeSinceLastStateChange
        {
            get 
            {
                return _timeSinceLastStateChange;
            }
        }

        public EQException EQException;
        public Action<UploadContext, UploadState> OnStateChange;
        public Action<EQException> OnError;

        public int RetryCount_Begin_Pending = 0;
        public int RetryCount_DownloadChunklist_Pending = 0;
        public int RetryCount_Complete_Pending = 0;
        public int RetryCount_CreateContentFile_Pending = 0;
        public int RetryCount_WaitingForAllToSee_Pending = 0;

        public bool Paused = false;
        public bool AutoPaused = false;

        public Upload Upload;
        public ContentFile ContentFile;

        public List<UploadChunk> UploadChunksInProgress = new List<UploadChunk>();

        public FileUploadSpec GetChunk(UploadChunk uploadChunk)
        {
            System.IO.FileStream stream = new System.IO.FileStream(Path, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            PartialStream streamPartial = new PartialStream(stream, (long)uploadChunk.ChunkOffset, (long)uploadChunk.ChunkSize);
            FileUploadSpec chunk = new FileUploadSpec(streamPartial, "chunk", null);
            return chunk;
        }

    }
}
