BookWithLibraryContainer.cs

130 lines | 2.957 kB Blame History Raw Download
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using System.Drawing;

using Tools.PdfProvider;

using Calibre.Model.Database.Entities;

using LibraryClass = Calibre.Model.Domain.Entities.Library;

namespace Calibre.Model.Domain.Entities
{
    /// <summary>
    /// Immutable
    /// </summary>
    public class BookWithLibraryContainer
    {
        #region Properties

        public Book Book { private set; get; }
        public ImmutableProxy<LibraryClass> Library { private set; get; }
        public byte[] Cover { private set; get; }

        #endregion


        private BookWithLibraryContainer() { }


        #region methods
                
        public async Task ReadFileAsync(
            Func<Stream, Task> readActionAsync
            )
        {
            await ReadFileAsync<int>(
                async (s) => 
                {
                    await readActionAsync(s);
                    return 0;
                }
                );
        }

        public async Task<T> ReadFileAsync<T>(
            Func<Stream, Task<T>> readActionAsync
            ) 
        {
            var filePath = LibraryClass.GetPdfFilePath(Library.Data, Book);
            using (var stream = File.OpenRead(filePath))
            {
                var result = await readActionAsync(stream);
                return result;
            }
        }

        public async Task<byte[]> ReadCoverAsync() 
        {
            var file = LibraryClass.GetCoverFilePath(Library, Book);
            if (!File.Exists(file))
            {
                return Array.Empty<byte>();
            }

            var coverBytes = await File.ReadAllBytesAsync(file);
            return coverBytes;
        }

        #endregion


        #region override

        public override int GetHashCode()
        {
            return Book.GetHashCode();
        }

        public override string ToString()
        {
            return Book.ToString();
        }

        #endregion


        #region static

        public async static Task<BookWithLibraryContainer> CreateAsync(
            Book book, 
            ImmutableProxy<LibraryClass> library,
            bool loadCover
            )
        {
            var item = new BookWithLibraryContainer() 
            {
                Book = book,
                Library = library
            };

            library.MutateValue(
                e => LibraryClass.AddBookContainer(library.Data, item)
                );

            item.Cover = loadCover
                ? await item.ReadCoverAsync()
                : Array.Empty<byte>();

            return item;
        }

        public static implicit operator Book(BookWithLibraryContainer container)
        {
            return container.Book;
        }

        public static implicit operator LibraryClass(BookWithLibraryContainer container)
        {
            return container.Library;
        }

        #endregion
    }
}