use core::ffi;

use ndk::android::configuration::*;

use crate::Assets;

#[repr(transparent)]
#[derive(Debug)]
pub struct Config {
	inner: *const AConfiguration,
}
impl Drop for Config {
	fn drop(&mut self) {
		unsafe { AConfiguration_delete(self.inner as _) }
	}
}
impl Config {
	pub fn new() -> Self {
		Self {
			inner: unsafe { AConfiguration_new() },
		}
	}
	pub fn copy_from_assets(&self, assets: &Assets) {
		unsafe { AConfiguration_fromAssetManager(self.inner as _, assets.as_sys()) }
	}
	pub fn mcc(&self) -> i32 {
		unsafe { AConfiguration_getMcc(self.inner as _) }
	}
	pub fn mnc(&self) -> i32 {
		unsafe { AConfiguration_getMnc(self.inner as _) }
	}
	pub fn language(&self) -> [ffi::c_char; 2] {
		let mut ret: [ffi::c_char; 2] = [0; 2];
		unsafe { AConfiguration_getLanguage(self.inner as _, ret.as_mut_ptr()) };
		ret
	}
	pub fn country(&self) -> [ffi::c_char; 2] {
		let mut ret: [ffi::c_char; 2] = [0; 2];
		unsafe { AConfiguration_getCountry(self.inner as _, ret.as_mut_ptr()) };
		ret
	}
	pub fn orientation(&self) -> Orientation {
		let ret = unsafe { AConfiguration_getOrientation(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_ORIENTATION_PORT => Orientation::Port,
			ACONFIGURATION_ORIENTATION_LAND => Orientation::Land,
			_ => Orientation::Any,
		}
	}
	pub fn touchscreen(&self) -> Touchscreen {
		let ret = unsafe { AConfiguration_getTouchscreen(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_TOUCHSCREEN_NOTOUCH => Touchscreen::NoTouch,
			ACONFIGURATION_TOUCHSCREEN_FINGER => Touchscreen::Finger,
			_ => Touchscreen::Any,
		}
	}
	pub fn density(&self) -> Density {
		let ret = unsafe { AConfiguration_getDensity(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_DENSITY_DEFAULT => Density::Default,
			ACONFIGURATION_DENSITY_LOW => Density::Low,
			ACONFIGURATION_DENSITY_MEDIUM => Density::Medium,
			ACONFIGURATION_DENSITY_TV => Density::Tv,
			ACONFIGURATION_DENSITY_HIGH => Density::Hign,
			ACONFIGURATION_DENSITY_XHIGH => Density::XHign,
			ACONFIGURATION_DENSITY_XXHIGH => Density::XXHign,
			ACONFIGURATION_DENSITY_XXXHIGH => Density::XXXHign,
			ACONFIGURATION_DENSITY_NONE => Density::None,
			_ => Density::Any,
		}
	}
	pub fn keyboard(&self) -> Keyboard {
		let ret = unsafe { AConfiguration_getKeyboard(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_KEYBOARD_NOKEYS => Keyboard::NoKeys,
			ACONFIGURATION_KEYBOARD_QWERTY => Keyboard::Qwerty,
			ACONFIGURATION_KEYBOARD_12KEY => Keyboard::Key12,
			_ => Keyboard::Any,
		}
	}
	pub fn navigation(&self) -> Navigation {
		let ret = unsafe { AConfiguration_getNavigation(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_NAVIGATION_DPAD => Navigation::DPad,
			ACONFIGURATION_NAVIGATION_NONAV => Navigation::NoNav,
			ACONFIGURATION_NAVIGATION_TRACKBALL => Navigation::TrackBall,
			ACONFIGURATION_NAVIGATION_WHEEL => Navigation::Wheel,
			_ => Navigation::Any,
		}
	}
	pub fn keyshidden(&self) -> KeysHidden {
		let ret = unsafe { AConfiguration_getKeysHidden(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_KEYSHIDDEN_NO => KeysHidden::No,
			ACONFIGURATION_KEYSHIDDEN_YES => KeysHidden::Yes,
			ACONFIGURATION_KEYSHIDDEN_SOFT => KeysHidden::Soft,
			_ => KeysHidden::Any,
		}
	}
	pub fn navhidden(&self) -> ConfigBool {
		let ret = unsafe { AConfiguration_getNavHidden(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_NAVHIDDEN_NO => ConfigBool::No,
			ACONFIGURATION_NAVHIDDEN_YES => ConfigBool::Yes,
			_ => ConfigBool::Any,
		}
	}
	pub fn sdk_version(&self) -> i32 {
		unsafe { AConfiguration_getSdkVersion(self.inner as _) }
	}
	pub fn screen_size(&self) -> ScreenSize {
		let ret = unsafe { AConfiguration_getScreenSize(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_SCREENSIZE_SMALL => ScreenSize::Small,
			ACONFIGURATION_SCREENSIZE_NORMAL => ScreenSize::Normal,
			ACONFIGURATION_SCREENSIZE_LARGE => ScreenSize::Large,
			ACONFIGURATION_SCREENSIZE_XLARGE => ScreenSize::XLarge,
			_ => ScreenSize::Any,
		}
	}
	pub fn screen_long(&self) -> ConfigBool {
		let ret = unsafe { AConfiguration_getScreenLong(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_SCREENLONG_NO => ConfigBool::No,
			ACONFIGURATION_SCREENLONG_YES => ConfigBool::Yes,
			_ => ConfigBool::Any,
		}
	}
	pub fn screen_round(&self) -> ConfigBool {
		let ret = unsafe { AConfiguration_getScreenRound(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_SCREENROUND_NO => ConfigBool::No,
			ACONFIGURATION_SCREENROUND_YES => ConfigBool::Yes,
			_ => ConfigBool::Any,
		}
	}
	pub fn ui_mode_type(&self) -> UiModeType {
		let ret = unsafe { AConfiguration_getUiModeType(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_UI_MODE_TYPE_NORMAL => UiModeType::Normal,
			ACONFIGURATION_UI_MODE_TYPE_DESK => UiModeType::Desk,
			ACONFIGURATION_UI_MODE_TYPE_CAR => UiModeType::Car,
			ACONFIGURATION_UI_MODE_TYPE_TELEVISION => UiModeType::Television,
			ACONFIGURATION_UI_MODE_TYPE_VR_HEADSET => UiModeType::VrHeadset,
			ACONFIGURATION_UI_MODE_TYPE_WATCH => UiModeType::Watch,
			ACONFIGURATION_UI_MODE_TYPE_APPLIANCE => UiModeType::Appliance,
			_ => UiModeType::Any,
		}
	}
	pub fn ui_mode_night(&self) -> ConfigBool {
		let ret = unsafe { AConfiguration_getUiModeNight(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_UI_MODE_NIGHT_NO => ConfigBool::No,
			ACONFIGURATION_UI_MODE_NIGHT_YES => ConfigBool::Yes,
			_ => ConfigBool::Any,
		}
	}
	pub fn screen_width_dp(&self) -> i32 {
		unsafe { AConfiguration_getScreenWidthDp(self.inner as _) }
	}
	pub fn screen_height_dp(&self) -> i32 {
		unsafe { AConfiguration_getScreenHeightDp(self.inner as _) }
	}
	pub fn smallest_screen_width_dp(&self) -> i32 {
		unsafe { AConfiguration_getSmallestScreenWidthDp(self.inner as _) }
	}
	pub fn layout_direction(&self) -> LayoutDirection {
		let ret = unsafe { AConfiguration_getLayoutDirection(self.inner as _) };
		match ret as u32 {
			ACONFIGURATION_LAYOUTDIR_LTR => LayoutDirection::Ltr,
			ACONFIGURATION_LAYOUTDIR_RTL => LayoutDirection::Rtl,
			_ => LayoutDirection::Any,
		}
	}
	pub fn diff(&self, other: &Self) -> i32 {
		unsafe { AConfiguration_diff(self.inner as _, other.inner as _) }
	}
}

pub enum Orientation {
	Any,
	Port,
	Land,
}
pub enum Touchscreen {
	Any,
	NoTouch,
	Finger,
}
pub enum Density {
	Default,
	Low,
	Medium,
	Tv,
	Hign,
	XHign,
	XXHign,
	XXXHign,
	Any,
	None,
}
pub enum Keyboard {
	Any,
	NoKeys,
	Qwerty,
	Key12,
}
pub enum Navigation {
	Any,
	NoNav,
	DPad,
	TrackBall,
	Wheel,
}
pub enum KeysHidden {
	Any,
	No,
	Yes,
	Soft,
}
pub enum ScreenSize {
	Any,
	Small,
	Normal,
	Large,
	XLarge,
}
pub enum UiModeType {
	Any,
	Normal,
	Desk,
	Car,
	Television,
	Appliance,
	Watch,
	VrHeadset,
}
pub enum LayoutDirection {
	Any,
	Ltr,
	Rtl,
}
pub enum ConfigBool {
	Any,
	No,
	Yes,
}
