use crate::egl::{Dimensions, Texture};
use error_backtrace::Backtraced;
use error_backtrace::GenericError;
use error_backtrace::Result as TraceResult;
use glium::{program, uniform};
use std::error::Error;
use super::Shader;
pub struct Crop;
impl Crop {
    pub fn new(facade: &impl glium::backend::Facade, dims: (u32, u32))
        -> Result<Shader<Self>, Box<dyn Error>>
    {
        Shader::<Self>::new_with_facade(facade, dims)
    }
}
impl Shader<Crop> {
    fn new_with_facade<F: glium::backend::Facade>(
        facade: &F,
        size: (u32, u32),
    ) -> Result<Self, Box<dyn Error>> {
        let (vertices, indices) = super::covering_vertices(facade, size)?;
        Ok(Self {
            program: program!(
                facade,
                120 => {
                    vertex: include_str!("crop/vert.glsl"),
                    fragment: include_str!("crop/frag.glsl"),
                }
            )?,
            vertices,
            indices,
            _data: Default::default(),
        })
    }
    
    pub fn convert<F: glium::backend::Facade>(
        &self,
        facade: &F,
        source_tex: Texture,
        target: &mut impl glium::Surface,
    ) -> TraceResult<(), GenericError>{
        let Dimensions { width: ws, height: hs } = source_tex.dimensions();
        let (wt, ht ) = target.get_dimensions();
        if wt > ws || ht > hs {
            Err(GenericError(Box::new(super::Error::BadDimensions {
                expected: Dimensions { width: wt, height: ht },
                got: source_tex.dimensions(),
                msg: "Neither target dimensions can exceed the source dimension",
            })))?;
        }
        Ok(
            self.draw_any(
                facade,
                source_tex,
                target,
                uniform! {},
            )
            .map_err(GenericError)?
        )
    }
}