﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace TP7
{
    /* Classe représentant le modèle du MVC
     * Contient principalement la liste des formes
     * */
    internal class Modele 
    {
        List<FormeGeo> tab_formes; //Liste de formes affichées
        public Modele() {
            tab_formes = new List<FormeGeo>();
        }

        public FormeGeo get(int i) { return tab_formes[i]; }

        public int getSize() { return tab_formes.Count; }

        public void add(FormeGeo f) { tab_formes.Add(f); }
    }

    /* Enum pour les différentes formes possibles */
    enum Type_Forme
    {
        Rectangle,
        Disque
    }

    /* Classe abstraite mère de toutes les formes */
    abstract class FormeGeo
    {
        protected int x, y; //Position de la forme (point en haut à gauche)
        protected FormeGeo(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public int getX() { return this.x; }

        public int getY() { return this.y; }

        public void setX(int x) { this.x = x; }

        public void setY(int y) { this.y = y; }

        //Renvoie vrai si les coordonnées sont dans la forme
        abstract public bool estDedans(int x, int y); 

        //Déplace la forme d'un delta x et y
        public void deplace(int dx, int dy)
        {
            this.x = this.x + dx;
            this.y = this.y + dy;
        }

        //Renvoie l'enum représentant le type de la forme
        abstract public Type_Forme GetTypeForme();
    }

    /* Classe représentant un rectangle
     * Elle est appelé FRectangle pour ne pas cacher la classe Rectangle
     * définie dans Windows Forms
     * */
    class FRectangle : FormeGeo
    {

        private int larg, haut;//la largeur et la hauteur du rectangle

        internal FRectangle (int x, int y, int larg, int haut) : base (x, y) {
            this.larg = larg;
            this.haut = haut;
        }

        public int getLargeur() { return larg; }
        public int getHauteur() { return haut; }
        public void setLargeur(int larg) { this.larg = larg; }
        public void setHauteur(int haut) { this.haut = haut; }

        public override bool estDedans(int x, int y)
        {
            return (x - this.x) < this.larg && (x - this.x) > 0 && (y - this.y) < this.haut && (y - this.y) > 0;
        }

        public override Type_Forme GetTypeForme() { return Type_Forme.Rectangle; }
    }

    /* Classe représentant un disque
     */
    class Disque : FormeGeo
    {
        private int rayon;

        internal Disque(int x, int y, int rayon) : base (x, y)
        {
            this.rayon = rayon;
        }

        public int getRayon() { return rayon; }

        public void setRayon(int rayon) { this.rayon = rayon; }

        public override bool estDedans(int x, int y) 
        {
            int xc = this.x + rayon;
            int yc = this.y + rayon;
            return (x - xc) * (x - xc) + (y - yc) * (y - yc) <= this.rayon * this.rayon;
        }

        public override Type_Forme GetTypeForme() { return Type_Forme.Disque; }
    }
}
