/*
 * ReadingPreferences.vala
 * 
 * Represents user reading/display preferences.
 * Following GNOME HIG naming conventions and Vala/GObject patterns.
 */

/**
 * FontSize - Available font size options
 */
public enum RSSuper.FontSize {
    SMALL,
    MEDIUM,
    LARGE,
    XLARGE
}

/**
 * LineHeight - Available line height options
 */
public enum RSSuper.LineHeight {
    NORMAL,
    RELAXED,
    LOOSE
}

/**
 * ReadingPreferences - User reading/display settings
 */
public class RSSuper.ReadingPreferences : Object {
    public FontSize font_size { get; set; }
    public LineHeight line_height { get; set; }
    public bool show_table_of_contents { get; set; }
    public bool show_reading_time { get; set; }
    public bool show_author { get; set; }
    public bool show_date { get; set; }
    
    public ReadingPreferences() {
        this.font_size = FontSize.MEDIUM;
        this.line_height = LineHeight.NORMAL;
        this.show_table_of_contents = true;
        this.show_reading_time = true;
        this.show_author = true;
        this.show_date = true;
    }
    
    public ReadingPreferences.with_values(FontSize font_size = FontSize.MEDIUM,
                                           LineHeight line_height = LineHeight.NORMAL,
                                           bool show_table_of_contents = true,
                                           bool show_reading_time = true,
                                           bool show_author = true,
                                           bool show_date = true) {
        this.font_size = font_size;
        this.line_height = line_height;
        this.show_table_of_contents = show_table_of_contents;
        this.show_reading_time = show_reading_time;
        this.show_author = show_author;
        this.show_date = show_date;
    }
    
    public string get_font_size_string() {
        switch (this.font_size) {
            case FontSize.SMALL: return "small";
            case FontSize.MEDIUM: return "medium";
            case FontSize.LARGE: return "large";
            case FontSize.XLARGE: return "xlarge";
            default: return "medium";
        }
    }
    
    public static FontSize font_size_from_string(string str) {
        switch (str) {
            case "small": return FontSize.SMALL;
            case "medium": return FontSize.MEDIUM;
            case "large": return FontSize.LARGE;
            case "xlarge": return FontSize.XLARGE;
            default: return FontSize.MEDIUM;
        }
    }
    
    public string get_line_height_string() {
        switch (this.line_height) {
            case LineHeight.NORMAL: return "normal";
            case LineHeight.RELAXED: return "relaxed";
            case LineHeight.LOOSE: return "loose";
            default: return "normal";
        }
    }
    
    public static LineHeight line_height_from_string(string str) {
        switch (str) {
            case "normal": return LineHeight.NORMAL;
            case "relaxed": return LineHeight.RELAXED;
            case "loose": return LineHeight.LOOSE;
            default: return LineHeight.NORMAL;
        }
    }
    
    public void reset_to_defaults() {
        this.font_size = FontSize.MEDIUM;
        this.line_height = LineHeight.NORMAL;
        this.show_table_of_contents = true;
        this.show_reading_time = true;
        this.show_author = true;
        this.show_date = true;
    }
    
    public string to_json_string() {
        var sb = new StringBuilder();
        sb.append("{\"fontSize\":\"");
        sb.append(this.get_font_size_string());
        sb.append("\",\"lineHeight\":\"");
        sb.append(this.get_line_height_string());
        sb.append("\",\"showTableOfContents\":");
        sb.append(this.show_table_of_contents ? "true" : "false");
        sb.append(",\"showReadingTime\":");
        sb.append(this.show_reading_time ? "true" : "false");
        sb.append(",\"showAuthor\":");
        sb.append(this.show_author ? "true" : "false");
        sb.append(",\"showDate\":");
        sb.append(this.show_date ? "true" : "false");
        sb.append("}");
        return sb.str;
    }
    
    public static ReadingPreferences? from_json_string(string json_string) {
        var parser = new Json.Parser();
        try {
            if (!parser.load_from_data(json_string)) return null;
        } catch (Error e) {
            warning("Failed to parse JSON: %s", e.message);
            return null;
        }
        return from_json_node(parser.get_root());
    }
    
    public static ReadingPreferences? from_json_node(Json.Node node) {
        if (node.get_node_type() != Json.NodeType.OBJECT) return null;
        var obj = node.get_object();
        var prefs = new ReadingPreferences();
        if (obj.has_member("fontSize")) prefs.font_size = font_size_from_string(obj.get_string_member("fontSize"));
        if (obj.has_member("lineHeight")) prefs.line_height = line_height_from_string(obj.get_string_member("lineHeight"));
        if (obj.has_member("showTableOfContents")) prefs.show_table_of_contents = obj.get_boolean_member("showTableOfContents");
        if (obj.has_member("showReadingTime")) prefs.show_reading_time = obj.get_boolean_member("showReadingTime");
        if (obj.has_member("showAuthor")) prefs.show_author = obj.get_boolean_member("showAuthor");
        if (obj.has_member("showDate")) prefs.show_date = obj.get_boolean_member("showDate");
        return prefs;
    }
    
    public bool equals(ReadingPreferences? other) {
        if (other == null) return false;
        return this.font_size == other.font_size &&
               this.line_height == other.line_height &&
               this.show_table_of_contents == other.show_table_of_contents &&
               this.show_reading_time == other.show_reading_time &&
               this.show_author == other.show_author &&
               this.show_date == other.show_date;
    }
    
    public void copy_from(ReadingPreferences other) {
        this.font_size = other.font_size;
        this.line_height = other.line_height;
        this.show_table_of_contents = other.show_table_of_contents;
        this.show_reading_time = other.show_reading_time;
        this.show_author = other.show_author;
        this.show_date = other.show_date;
    }
}
