#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum WidgetDescription {
    TabBook(TabBookDescription),
    ResultGrid(ResultGridDescription),
    AlignmentBox(AlignmentBoxDescription),
    PropertyBox(PropertyBoxDescription),
    Curve(CurveDescription),
    ResultTable(ResultTableDescription),
    StatisticsTable(StatisticsTableDescription),
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum WidgetDescriptionWithProperty {
    ResultTable(ResultTableDescription),
    StatisticsTable(StatisticsTableDescription),
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TabPosition {
    North,
    East,
    South,
    West,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Orientation {
    Horizontal,
    Vertical,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct TabBookDescription {
    pub tabs: Vec<TabPageDescription>,
    pub tab_position: TabPosition,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum TabLabelDescription {
    ThemeIcon(IconReference),
    DeviceIcon(IconReference),
    Caption(Caption),
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct IconReference {
    pub icon: String,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct CurveDescription {
    pub curve: String,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct Caption {
    #[serde(rename = "_caption")]
    pub caption: String,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct TabPageDescription {
    pub label: TabLabelDescription,
    pub child: Box<WidgetDescription>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct ResultGridDescription {
    pub columns: u8,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct AlignmentBoxDescription {
    pub children: Vec<AlignmentBoxChildDescription>,
    pub orientation: Orientation,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct AlignmentBoxChildDescription {
    pub child: Box<WidgetDescription>,
    pub relative_width: u32,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct PropertyBoxDescription {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub child: Option<WidgetDescriptionWithProperty>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct ResultTableDescription {}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct StatisticsTableDescription {}
