//! Compiling specific font tables
//!
//! The primary purpose of FEA is compiling GPOS/GSUB tables, but additional
//! tables may be generated as well. The fea spec supports special syntax
//! for specifying values for [a number of additional tables][spec]; in addition
//! to this, some tables (specifically GDEF) may be generated by the compiler
//! as required.
//!
//! [spec]: http://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9-specifying-or-overriding-table-values

use write_fonts::{
    from_obj::ToOwnedTable,
    read::{FontRef, TableProvider},
    tables::{
        self,
        variations::ivs_builder::{VariationIndexRemapping, VariationStoreBuilder},
    },
    types::{Fixed, LongDateTime},
};

use crate::common::GlyphId;

mod base;
mod gdef;
mod name;
mod os2;
mod stat;

pub(crate) use base::{BaseBuilder, ScriptRecord};
pub(crate) use gdef::{GdefBuilder, GlyphClassDefExt};
pub(crate) use name::{NameBuilder, NameSpec};
pub(crate) use os2::{CodePageRange, Os2Builder};
pub(crate) use stat::{AxisLocation, AxisRecord, AxisValue, StatBuilder, StatFallbackName};

/// The explicit tables allowed in a fea file
#[derive(Clone, Debug, Default)]
pub(crate) struct Tables {
    pub head: Option<HeadBuilder>,
    pub hhea: Option<tables::hhea::Hhea>,
    pub vhea: Option<tables::vhea::Vhea>,
    pub vmtx: Option<VmtxBuilder>,
    pub name: NameBuilder,
    pub gdef: Option<GdefBuilder>,
    pub base: Option<BaseBuilder>,
    pub os2: Option<Os2Builder>,
    pub stat: Option<StatBuilder>,
}

#[derive(Clone, Debug, Default)]
pub(crate) struct HeadBuilder {
    pub font_revision: Fixed,
}

#[derive(Clone, Debug, Default)]
pub(crate) struct VmtxBuilder {
    pub origins_y: Vec<(GlyphId, i16)>,
    pub advances_y: Vec<(GlyphId, i16)>,
}

// this is the value used in python fonttools when writing this table
const DATE_2011_12_13_H11_M22_S33: LongDateTime = LongDateTime::new(1323780153);

impl HeadBuilder {
    pub(crate) fn build(&self, font: Option<&FontRef>) -> write_fonts::tables::head::Head {
        // match what python fonttools does
        let mut head = font
            .and_then(|f| f.head().map(|x| x.to_owned_table()).ok())
            .unwrap_or_else(|| {
                let mut head = write_fonts::tables::head::Head {
                    created: DATE_2011_12_13_H11_M22_S33,
                    modified: DATE_2011_12_13_H11_M22_S33,
                    ..Default::default()
                };

                // I think we should still use the known default values but this matches
                // feaLib tests so :shrug:
                head.magic_number = 0;
                head.font_direction_hint = 0;
                head
            });
        head.font_revision = self.font_revision;
        head
    }
}
