use std::iter::Iterator;
use super::{Circ, Line, Rect, Shape, Vector2};

pub struct Poly {
    pub pos: Vector2,
    pub rotation: f32,
    pub scale: f32,
    pub origin: Vector2,
    pub points: Vec<Vector2>,
}

impl Poly {
    pub fn new(pos: Vector2, points: Vec<Vector2>) -> Poly {
        Poly {
            pos: pos,
            origin: Vector2::new(0f32, 0f32),
            rotation: 0f32,
            scale: 1f32,
            points: points,
        }
    }

    pub fn from_rect(rect: Rect, origin: Vector2) -> Poly {
        Poly {
            pos: Vector2::new(rect.x, rect.y),
            origin: origin,
            rotation: 0f32,
            scale: 1f32,
            points: vec![Vector2::new(0f32, 0f32),
                         Vector2::new(0f32, rect.height),
                         Vector2::new(rect.width, rect.height),
                         Vector2::new(rect.width, 0f32)],
        }
    }

    pub fn vertex(&self, index: usize) -> Vector2 {
        let original = self.points[index];
        // Transform the vector with the origin
        let moved = original - self.origin;
        // Rotate and scale the vector
        let transformed = moved.rotate(self.rotation).scl(self.scale);
        // Move the transformed vector back into the correct coordinate space
        transformed + self.pos + self.origin
    }
}

impl Shape for Poly {
    fn set_position(&mut self, x: f32, y: f32) -> () {
        self.pos.x = x;
        self.pos.y = y;
    }
    fn get_position(&self) -> Vector2 {
        return self.pos;
    }
    fn intersects(&self, line: Line) -> bool {
        for i in 0..(self.points.len() + 1) {
            let one = self.vertex(i % self.points.len());
            let two = self.vertex((i + self.points.len() - 1) % self.points.len());
            let face = Line::new(one, two);
            if line.intersects(face) {
                return true;
            }
        }
        return false;
    }
    fn contains(&self, point: Vector2) -> bool {
        let mut i = 0;
        let mut j = self.points.len() - 1;
        let mut c = 0;
        while i < self.points.len() {
            if ((self.vertex(i).y > point.y) != (self.vertex(j).y > point.y)) &&
               (point.x <
                (self.vertex(j).x - self.vertex(i).x) * (point.y - self.vertex(i).y) /
                (self.vertex(j).y - self.vertex(i).y) + self.vertex(i).x) {
                c = !c;
            }
            j = i;
            i += 1;
        }
        return c != 0;
    }
    fn overlaps_rect(&self, rect: Rect) -> bool {
        self.overlaps(&rect)
    }
    fn overlaps_circ(&self, circ: Circ) -> bool {
        self.overlaps(&circ)
    }
    fn overlaps_poly(&self, poly: &Poly) -> bool {
        self.overlaps(poly)
    }
    fn overlaps<T: Shape>(&self, shape: &T) -> bool {
        if self.contains(shape.get_position()) 

        for i in 0..(self.points.len() + 1) {
            let one = self.vertex(i % self.points.len());
            let two = self.vertex((i + self.points.len() - 1) % self.points.len());
            let face = Line::new(one, two);
            println!("{}:{}, {}:{}", one.x, one.y, two.x, two.y);
            if shape.contains(one) || shape.intersects(face) {
                return true;
            }
        }
        return false;
    }
    fn get_bounding_box(&self) -> Rect {
        let get_x = |vector: &Vector2| vector.x;
        let get_y = |vector: &Vector2| vector.y;
        let minimum = |a, b| { if b < a { b } else { a } };
        let maximum = |a, b| { if b > a { b } else { a } };
        let x = self.points[0].x;
        let y = self.points[0].y;
        let min_x = self.points.iter().map(&get_x).fold(x, &minimum);
        let min_y = self.points.iter().map(&get_y).fold(y, &minimum);
        let max_x = self.points.iter().map(&get_x).fold(x, &maximum);
        let max_y = self.points.iter().map(&get_y).fold(y, &maximum);
        Rect::new(min_x, min_y, max_x - min_x, max_y - min_y)
    }
}

{
            return true;
        }