/**
 * @file Arquivo contendo a logica para a manipulação do canvas para exibição de uma galeria de fotos
 * @version 0.0.1
 * @author Gustavo Henrique S. S. de Miranda    
 */

/**
 * @author Gustavo Henrique S. S. de Miranda 
 * @class
 * @classdesc Classe Geral da Aplicação contendo a base da Aplicação
 * 
 */
class PhotoViewAPP{
    /**
     * @constructs
     * @description Constructor da classe que obtem dados do Canvas
     */
    constructor(){
        this.context = new PhotoViewContext()
        this.canvas = this.setCanvasFromID()
        this.canvasContext =this.setCanvasContext()
        this.canvasCRect = this.setCanvasCRect()
        console.log(this.context.getstate())
    }
    /**
     * @description Obtém o Canvas do documentos html pelo ID dado ao mesmo
     * @returns Retorna O Canvas
     * @todo Alterar para a propiedade this.canvas
     */
    setCanvasFromID() {
        return document.querySelector('#PhotoView')    
    }
    /**
     * @description Define o contexto do canvas
     */
    setCanvasContext(){
         this.canvasContext = this.canvas.getContext('2d')
    }
    /**
     * @description Obtém a posição do canvas na página index.html
     */
    setCanvasCRect(){
        this.canvasCRect = this.canvas.getBoundingClientRect()
    
    }
    /**
     * @description Define o evento de onClick da tag canvas
     */
    setCanvasClickEvent(){
        this.canvas.addEventListener('click',(e)=>{this.context.clickEvent(e)})
    }
    /**
     * @description Inicializa o a aplicação 
     */
    initalizePhotoViewApp(){
        this.setCanvasClickEvent()
    }
}


/**
 * @author Gustavo Henrique S. S. de Miranda 
 * @class
 * 
 * @classdesc Contexto para Gerencias as telas da aplicação
 */
class PhotoViewContext{
    #state = null
    #stateList = {}
    /**
     * @constructs
     * @param {*} state Tela Inicial a ser exibida na aplicação 
     */
    constructor(state){
        this.#state = state
        

    }
    /**
     * 
     * @description Add a view to a list of views 
     * @param {*} state state to be added
     * @param {*} statename name of the state to be added 
     */
    addToStateList(state,statename){
        this.#stateList[statename] = new state();
    }
    /**
     * @description Gets a view on the list of views
     * @param {*} statename Name of the view to be returned
     * @returns The view on the list
     */
    getStateByName(statename){
        return this.#stateList[statename]
    }
    /**
     * 
     * @returns the current view 
     */
    getstate(){
        return this.#state
    }
    
}

/**
 * @author Gustavo Henrique S. S. de Miranda 
 * @class
 * @classdesc Abstract Class to be extended as a screen for the app
 * @abstract
 */
class abstractStateClass{
    #parentClass = null
    /**
     * @constructs
     * 
     */
    constructor(){
        if (this.constructor == abstractStateClass){
            throw new Error("Abstract Class  not should not be instatiated")
        }
    }
    /**
     * 
     * @param {*} parentclass Reference of the parent class
     * @description Defines a reference to the parent class to access its methods and attributes
     */
    #setParentClass(parentclass){
        this.#parentClass = parentclass
    }
}


/**
 * @author Gustavo Henrique S. S. de Miranda 
 * @class
 * @classdesc Represents a thumbnail view for the app
 * @extends abstractStateClass
 */

class thumbnailView extends abstractStateClass{
    constructor(){

    }
}

function contextGetter(){
    var c = document.querySelector("#PhotoView")
    

    return c.getContext('2d')
}


async function GetImages(){
    var file = await fetch('imgs/imgs.json')
    var data = await file.json()
    var imgArray = []
    var numberImgs = data.images.length
    data.images.forEach(element => {
        var img = new Image(192,108)
        img.src = 'imgs/'+element
        imgArray.push(img)
    });
    return imgArray

    
}


async function LoadImages(Context,ListOfImages){
    var  ImgObjList = []
    var currentX = 672
    var currentY = 378
    var MaxRows = 3
    var MaxCols = 3
    var CurrentRow = 0
    var CurrentCol = 0
    await Promise.all(ListOfImages.map((element)=>{
        return new Promise(resolve => {
            element.onload = function() {
                
                Context.drawImage(element,currentX,currentY,192,108)
                ImgObjList.push({"img":element,
                    "pos":{
                        "x":{
                            "start":currentX,
                            "end": currentX + 192
                        },
                        "y":{
                            "start":currentY,
                            "end": currentY + 108
                        }
                    }
                })
                
                if (CurrentRow == MaxRows - 1 ){
                    CurrentCol++
                    currentY += 110
                    CurrentRow = 0
                    currentX = 672
                }else{
                    currentX += 194
                    CurrentRow++

                }
                resolve();
            }
        });
         
    }));

    
 
}
 
function PositionImages(ListOfImages){
    var  ImgObjList = []
    var CurrentRow = 0
    var CurrentCol = 0
    var MaxCols = 3
    var MaxRows = 3
    var CurrentX = 672
    var CurrentY = 378
    var ImgWidth = ListOfImages[0].width
    var ImgHeight = ListOfImages[0].height
    ListOfImages.map((element)=>{
        ImgObjList.push({
            "img":element,
            "pos":{
                "x":{
                    "start":CurrentX,
                    "end":CurrentX + 192
                },
                "y":{
                    "start":CurrentY,
                    "end":CurrentY + 108
                }
            }
        })
        if (CurrentRow == MaxRows - 1){
            CurrentCol++
            CurrentY += 110
            CurrentRow = 0
            CurrentX = 672
        }
        else{
            CurrentX += 194
            CurrentRow++
        }

    })
    return ImgObjList
}    


function CanvasClickEvent(e,canvasSize,ListOfImages) {
    var mouseX = (e.clientX - canvasSize.left)
    var mouseY = (e.clientY - canvasSize.top)
    //console.log(Math.floor((mouseX-672)/194))
    //console.log(Math.floor((mouseY-378)/110))
    
    if (( mouseX >= 672) && (mouseX <= ((194 * 3)+672)) && (( mouseY >= 378 ) && (mouseY <= ((110 * 3) + 378) ) )){
        ListOfImages.forEach(element=>{
            if ((mouseX >= element.pos.x.start) && (mouseX <= element.pos.x.end)){
                console.log(element)
            }
        })
        alert( mouseX + "\n" + mouseY)
    }
    
}

export  async function InitializePhotoViewApp(){
    
    var APP = new PhotoViewAPP();
    APP.initalizePhotoViewApp();

    var context = contextGetter();
    var arrayOfImages = await GetImages()
    LoadImages(context,arrayOfImages)
    var PositionedImages = PositionImages(arrayOfImages)
    var canvas = document.querySelector('#PhotoView')
    var cRect = canvas.getBoundingClientRect()

    canvas.addEventListener('click',(e)=>{CanvasClickEvent(e,cRect,PositionedImages)})
    

    

}