class Selectable {
    is_selected = false;
    x = 0;
    y = 0;    

    select() {
        this.is_selected = true;
    }
    unselect() {
        this.is_selected = false;
    }
    draw_selection() {

    }
    setSelectPosition(X ,Y) {
        this.x = X;
        this.y = Y;
    }
}

class KeyListener {
    key;
    execute() {

    }
    executeOnKey(event_key) {
        if(event_key == this.key) {
            this.execute();
        }
    }
}

class Screen {
    elements = [];

    selectable_objects = [];
    current_selected_element;
    user_select_position = {x: 0, y: 0};
    max_select_position = {x: 2, y: 2};

    user_can_select=false; // user can choose elements
    user_can_navigate=false; // user can go to another screen
    
    ctx;

    constructor(ctx) {
        this.ctx = ctx;

        this.onFrame = this.onFrame.bind(this);
    }

    addElement(elem) {
        this.elements.push(elem);
    }

    drawAll() {
        this.ctx.clearRect(0,0, windowSize.width, windowSize.height);
        this.elements.forEach(element => {
            this.ctx.save();
            element?.draw(this.ctx);
            this.ctx.restore();
        });
    }


    updateAll() {
        
        this.elements.forEach(element => {
            element?.update();
        });
    }


    onFrame() {
        this.drawAll();
        
        this.updateAll();

        requestAnimationFrame(this.onFrame);
    }

    keypress(event) {
        if(this.user_can_select == true) {
            this.select_key_event(event.key);
           
            
        }
    }
    
    select_key_event(key) {
        if(key == "d") {
            this.select_go_right();
        }
        if(key == "a") {
            this.select_go_left();
        }
        if(key == "s") {
            this.select_go_down();
        }
        if(key == "w") {
            this.select_go_up();
        }
    }
    
    

    

    select_go_right() {
        if(this.user_select_position.x == this.max_select_position.x - 1) {
               this.set_select_positionX(0);
        }
        else {
            this.set_select_positionX(this.user_select_position.x + 1);
        }
    }
    select_go_left() {
        if(this.user_select_position.x == 0) {
               this.set_select_positionX(this.max_select_position.x - 1);
        }
        else {
            this.set_select_positionX(this.user_select_position.x - 1);
        }
    }
    select_go_down() {
        if(this.user_select_position.y == this.max_select_position.y - 1) {
               this.set_select_positionY(0);
        }
        else {
            this.set_select_positionY(this.user_select_position.y + 1);
        }
    }
    select_go_up() {
        if(this.user_select_position.y == 0) {
               this.set_select_positionY(this.max_select_position.y - 1);
        }
        else {
            this.set_select_positionY(this.user_select_position.y - 1);
        }
    }
    set_select_positionX(x) {
        this.user_select_position.x = x;
        this.select_position_changed();
    }
    set_select_positionY(y) {
        this.user_select_position.y = y;
        this.select_position_changed();
    }
    select_position_changed() {
        if(this.current_selected_element != null) {
            this.current_selected_element.unselect();
        }
        this.select(this.get_select_object(this.user_select_position))
        
    }
    get_select_object(pos) {
        var result = null;
        
        this.selectable_objects.forEach(element => {
            if(element.x == pos.x && element.y == pos.y) {
                result = element;        
            }
        })
        return result;
    }
    select(obj) {
        obj.select();
        this.current_selected_element = obj;
    }
    unselect() {
        this.current_selected_element.unselect();
        this.current_selected_element = null;
    }
    makeSelectable(obj) {
        var select_obj = new Selectable();
        Object.assign(obj, select_obj);
        obj.select = select_obj.select;
        obj.unselect = select_obj.unselect;
        obj.draw_selection = select_obj.draw_selection;
        obj.setSelectPosition  = select_obj.setSelectPosition;
        
    }
    addToSelectable(obj, pos) {
        obj.setSelectPosition(pos.x, pos.y);
        this.selectable_objects.push(obj);
    }
}

class MainMenu extends Screen{

    constructor(ctx) {
        super(ctx);
    }

    load() {
        
        
    }

    
}







/* Sprite, must place after Rectangle
class Sprite extends Rectangle{

} */


class Shape {
    startX;
    startY;

    originX;
    originY;
    
    color;

    rotation = 0;

    draw(ctx) {
       
    }

    update() {
        
        
    }

    

    translate(x, y) {
        this.startX = x;
        this.startY = y;
    }
    translateX(x) {
        this.startX = x;
    }
    translateY(y) {
        this.startY = y;
    } 

}
class Rectangle extends Shape{
    width;
    height;

    constructor(startX, startY, width, height, color) {
        super()
        this.startX = startX;
        this.startY = startY;
        this.width = width;
        this.height = height;
        this.color = color;

        this.originX = startX;
        this.originY = startY;
    }

    draw(ctx) {
        ctx.translate(this.originX, this.originY); 
        ctx.rotate(this.rotation);
        ctx.translate(-(this.originX), -(this.originY)); 
        ctx.fillStyle = this.color;
        ctx.fillRect(this.startX,this.startY, this.width,this.height);

        if("is_selected" in this) {
            if(this.is_selected) {
                this.draw_selection(ctx);
            }
            
        }
    }
    drawStroke(ctx) {
        ctx.strokeStyle = "blue";
        ctx.lineWidth = 5;
        ctx.strokeRect(this.startX, this.startY,this.width,this.height);
    }

    setCenterOrigin() {
        this.originX = this.startX + this.width / 2;
        this.originY = this.startY + this.height / 2;
    }
}

class Text extends Shape{
    value;
    font;

    constructor(value, x,y, font, color) {
        super();
        this.value = value;
        this.font = font;
        this.x = x;
        this.y = y;
        this.color = color;
    }

    draw(ctx) {
        ctx.font = this.font;
        ctx.fillStyle = this.color;
        ctx.fillText(this.value, this.x, this.y);
    }

    setValue(newValue) {
        this.value = newValue;
    }
    getValue() {
        return this.value;
    }

    getWidth(ctx) {
        return ctx.measureText(this.value);
    }
    getCenterXFrom(ctx, x, maxWidth) {
        let width = this.getWidth(ctx).width;
        let a = x + (maxWidth / 1);     
        return (a + (width / (this.value.length + 1)));
    }
}

class Sprite extends Rectangle {
    img;
    src;

    constructor(x,y,w,h,src) {
        super(x,y,w,h,"green");
        this.src = src;

        this.img = new Image();
        this.img.src = this.src;
    }

    draw(ctx) {
        ctx.translate(this.originX, this.originY); 
        ctx.rotate(this.rotation);
        ctx.translate(-(this.originX), -(this.originY)); 

        ctx.drawImage(this.img,this.startX,this.startY, this.width,this.height);

        if("is_selected" in this) {
            if(this.is_selected) {
                this.draw_selection(ctx);
            }
            
        }
    }

}




class Line extends Shape {
    startX;
    startY;
    endX;
    endY;
    color;

    width = 5;

    constructor(startX, startY, endX, endY, color) {
        super();
        this.startX = startX;
        this.startY = startY;
        this.endX = endX;
        this.endY = endY;

        this.color = color;
    
        
    }

    draw(ctx) {
        ctx.moveTo(this.startX, this.startY);
        ctx.lineTo(this.endX, this.endY);
        ctx.lineWidth =  this.width;
        ctx.stroke();
    }
    update() {

    }
}






class Circle  extends Shape{
    radius;
}