using System;
using System.Collections.Generic;
using Orienteering.Standard;

namespace Orienteering.Data {
    public class Object {
        protected double x, y;
        protected int number;
        protected Orienteering.Data.Stage stage;

        public double X {
            get { return x; }
            set { x = value; }
        }
        public double Y {
            get { return y; }
            set { y = value; }
        }
        public int Number {
            get { return number; }
            set { number = value; }
        }
        public Stage Stage {
            get { return stage; }
            set { stage = value; }
        }

        public Object () {
        }

        public Object(double _x, double _y, int _number, Stage _stage) {
            x = _x; y = _y;
            number = _number;
            stage = _stage;
        }

        public void Save(DataBase dataBase) {
            dataBase.db.Set(this);
        }

    }

    public class Control : Object {
        public Control() {
        }
        public Control(double _x, double _y, int _number, Stage _stage) :
            base (_x, _y, _number, _stage) {
        }
    }

    public class Start : Object {
        public Start() {
        }
        public Start(double _x, double _y, int _number, Stage _stage) :
            base (_x, _y, _number, _stage) {
        }
    }

    public class Finish : Object {
        public Finish() {
        }
        public Finish(double _x, double _y, int _number, Stage _stage) :
            base (_x, _y, _number, _stage) {
        }
    }

    public class Course {
        private string name;
        private List<Object> objects;
        private Stage stage;

        public Course() {
            objects = new List<Object>();
        }

        public Course(string _name, Stage _stage) {
            name = _name;
            stage = _stage;
            objects = new List<Object>();
        }

        public void AddObject(Object obj) {
            objects.Add(obj);
        }

        public List<Object> Objects {
            get { return objects; }
        }

        public Stage Stage {
            get { return stage; }
            set { stage = value; }
        }

        public List<Category> Categories(DataBase dataBase) {
            return new List<Category>(
                dataBase.db.Query<Category>(
                    delegate(Category category) {
                        return category.Course == this;
                    }
                )
            );
        }

        public Category Category(string name, DataBase dataBase) {
            IList<Category> res = dataBase.db.Query<Category>(
                    delegate(Category category) {
                        return category.Name == name && category.Course == this;
                    }
                );
            if (res.Count == 0)
                throw new DoesntExist();
            else return res[0];
        }

        public string Name {
            get { return name; }
            set { name = value; }
        }

        public void Save(DataBase dataBase) {
            dataBase.db.Set(this);
        }

    }
}
