use std::io::Error as IoError;

use glc::error::Error as GlcError;
use glutin::{
    error::ExternalError as GlutinExternalError, ContextError as GlutinContextError,
    CreationError as GlutinCreationError,
};
use glyph_brush::ab_glyph::InvalidFont;
use serde_json::Error as JsonError;
use space_crush_common::{misc::VfsError, Error as CommonError};
use thiserror::Error;

#[derive(Debug, Error)]
pub enum Error {
    #[error("IO Error: {0}")]
    IoError(IoError),

    #[error("JSON Error: {0}")]
    JsonError(JsonError),

    #[error("GLC Error: {0}")]
    GlcError(GlcError),

    #[error("glutin Context Error: {0}")]
    GlutinContextError(GlutinContextError),

    #[error("glutin Creation Error: {0}")]
    GlutinCreationError(GlutinCreationError),

    #[error("glutin External Error: {0}")]
    GlutinExternalError(GlutinExternalError),

    #[error("Invalid Font: {0}")]
    InvalidFont(InvalidFont),

    #[error("VFS Error: {0}")]
    VfsError(VfsError),

    #[error("{0}")]
    CommonError(CommonError),

    #[error("Resource is not registered: {0}!")]
    ResourceNotRegistered(&'static str),

    #[error("Unable to create OpenGL context!")]
    CreateContext,

    #[error("Font is not set!")]
    FontNotSet,
}

impl From<IoError> for Error {
    fn from(err: IoError) -> Self {
        Self::IoError(err)
    }
}

impl From<JsonError> for Error {
    fn from(err: JsonError) -> Self {
        Self::JsonError(err)
    }
}

impl From<GlcError> for Error {
    fn from(err: GlcError) -> Self {
        Self::GlcError(err)
    }
}

impl From<GlutinContextError> for Error {
    fn from(err: GlutinContextError) -> Self {
        Self::GlutinContextError(err)
    }
}

impl From<GlutinCreationError> for Error {
    fn from(err: GlutinCreationError) -> Self {
        Self::GlutinCreationError(err)
    }
}

impl From<GlutinExternalError> for Error {
    fn from(err: GlutinExternalError) -> Self {
        Self::GlutinExternalError(err)
    }
}

impl From<InvalidFont> for Error {
    fn from(err: InvalidFont) -> Self {
        Self::InvalidFont(err)
    }
}

impl From<VfsError> for Error {
    fn from(err: VfsError) -> Self {
        Self::VfsError(err)
    }
}

impl From<CommonError> for Error {
    fn from(err: CommonError) -> Self {
        Self::CommonError(err)
    }
}
