// Path: src/main/java/org/hildan/fxgson/adapters/extras/ColorTypeAdapter.java
// public class ColorTypeAdapter extends TypeAdapter<Color> {
// 
//     @Override
//     public void write(JsonWriter out, Color value) throws IOException {
//         if (value == null) {
//             out.nullValue();
//             return;
//         }
//         int red = (int) Math.round(value.getRed() * 255.0);
//         int green = (int) Math.round(value.getGreen() * 255.0);
//         int blue = (int) Math.round(value.getBlue() * 255.0);
//         int opacity = (int) Math.round(value.getOpacity() * 255.0);
//         String colorStr = String.format("#%02x%02x%02x%02x", red, green, blue, opacity);
//         out.value(colorStr);
//     }
// 
//     @Override
//     public Color read(JsonReader in) throws IOException {
//         if (in.peek() == JsonToken.NULL) {
//             in.nextNull();
//             return null;
//         }
//         String value = in.nextString();
//         try {
//             return Color.web(value);
//         } catch (IllegalArgumentException e) {
//             throw new InvalidColorException(value, in.getPath(), e);
//         }
//     }
// 
//     public static class InvalidColorException extends RuntimeException {
// 
//         private static final String MSG_TEMPLATE =
//                 "Invalid color format '%s' at path %s, please use a format supported by Color.web()";
// 
//         InvalidColorException(String value, String path, Throwable cause) {
//             super(String.format(MSG_TEMPLATE, value, path), cause);
//         }
//     }
// }
// 
// Path: src/main/java/org/hildan/fxgson/adapters/extras/FontTypeAdapter.java
// public class FontTypeAdapter extends TypeAdapter<Font> {
// 
//     @Override
//     public void write(JsonWriter out, Font value) throws IOException {
//         if (value == null) {
//             out.nullValue();
//             return;
//         }
//         String family = value.getFamily();
//         String style = value.getStyle();
//         double size = value.getSize();
//         out.value(family + "," + style + "," + size);
//     }
// 
//     @Override
//     public Font read(JsonReader in) throws IOException {
//         if (in.peek() == JsonToken.NULL) {
//             in.nextNull();
//             return null;
//         }
//         String value = in.nextString();
//         String path = in.getPath();
// 
//         String[] components = splitComponents(value, path);
//         String family = components[0];
//         String style = components[1];
//         String sizeStr = components[2];
// 
//         FontWeight weight = extractWeight(style);
//         FontPosture posture = extractPosture(style);
//         double size = extractSize(sizeStr, path);
// 
//         return Font.font(family, weight, posture, size);
//     }
// 
//     private static String[] splitComponents(String value, String path) {
//         String[] font = value.split(",");
//         if (font.length < 3) {
//             throw InvalidFontException.missingComponent(value, path);
//         }
//         return font;
//     }
// 
//     private static FontWeight extractWeight(String style) {
//         for (String styleWord : style.split("\\s")) {
//             FontWeight weight = FontWeight.findByName(styleWord);
//             if (weight != null && weight != FontWeight.NORMAL) {
//                 return weight;
//             }
//         }
//         return FontWeight.NORMAL;
//     }
// 
//     private static FontPosture extractPosture(String style) {
//         for (String styleWord : style.split("\\s")) {
//             FontPosture posture = FontPosture.findByName(styleWord);
//             if (posture != null && posture != FontPosture.REGULAR) {
//                 return posture;
//             }
//         }
//         return FontPosture.REGULAR;
//     }
// 
//     private static double extractSize(String size, String path) {
//         try {
//             return Double.parseDouble(size);
//         } catch (NumberFormatException e) {
//             throw InvalidFontException.invalidSize(size, path, e);
//         }
//     }
// 
//     public static class InvalidFontException extends RuntimeException {
// 
//         InvalidFontException(String message) {
//             super(message);
//         }
// 
//         InvalidFontException(String message, Throwable cause) {
//             super(message, cause);
//         }
// 
//         static InvalidFontException missingComponent(String value, String path) {
//             return new InvalidFontException("Missing component in the font at path " + path + ", got '" + value + "'");
//         }
// 
//         static InvalidFontException invalidSize(String value, String path, Throwable cause) {
//             return new InvalidFontException("Invalid size for the font at path " + path + ", got '" + value + "'",
//                     cause);
//         }
//     }
// }


import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import org.hildan.fxgson.adapters.extras.ColorTypeAdapter;
import org.hildan.fxgson.adapters.extras.FontTypeAdapter;
package org.hildan.fxgson.factories;



/**
 * A {@link TypeAdapterFactory} for JavaFX's {@link Color} and {@link Font} classes.
 */
public class JavaFxExtraTypeAdapterFactory implements TypeAdapterFactory {

    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        Class<? super T> clazz = type.getRawType();

        if (Color.class.isAssignableFrom(clazz)) {
            return (TypeAdapter<T>) new ColorTypeAdapter();
        }

        if (Font.class.isAssignableFrom(clazz)) {
// Path: src/main/java/org/hildan/fxgson/adapters/extras/ColorTypeAdapter.java
// public class ColorTypeAdapter extends TypeAdapter<Color> {
// 
//     @Override
//     public void write(JsonWriter out, Color value) throws IOException {
//         if (value == null) {
//             out.nullValue();
//             return;
//         }
//         int red = (int) Math.round(value.getRed() * 255.0);
//         int green = (int) Math.round(value.getGreen() * 255.0);
//         int blue = (int) Math.round(value.getBlue() * 255.0);
//         int opacity = (int) Math.round(value.getOpacity() * 255.0);
//         String colorStr = String.format("#%02x%02x%02x%02x", red, green, blue, opacity);
//         out.value(colorStr);
//     }
// 
//     @Override
//     public Color read(JsonReader in) throws IOException {
//         if (in.peek() == JsonToken.NULL) {
//             in.nextNull();
//             return null;
//         }
//         String value = in.nextString();
//         try {
//             return Color.web(value);
//         } catch (IllegalArgumentException e) {
//             throw new InvalidColorException(value, in.getPath(), e);
//         }
//     }
// 
//     public static class InvalidColorException extends RuntimeException {
// 
//         private static final String MSG_TEMPLATE =
//                 "Invalid color format '%s' at path %s, please use a format supported by Color.web()";
// 
//         InvalidColorException(String value, String path, Throwable cause) {
//             super(String.format(MSG_TEMPLATE, value, path), cause);
//         }
//     }
// }
// 
// Path: src/main/java/org/hildan/fxgson/adapters/extras/FontTypeAdapter.java
// public class FontTypeAdapter extends TypeAdapter<Font> {
// 
//     @Override
//     public void write(JsonWriter out, Font value) throws IOException {
//         if (value == null) {
//             out.nullValue();
//             return;
//         }
//         String family = value.getFamily();
//         String style = value.getStyle();
//         double size = value.getSize();
//         out.value(family + "," + style + "," + size);
//     }
// 
//     @Override
//     public Font read(JsonReader in) throws IOException {
//         if (in.peek() == JsonToken.NULL) {
//             in.nextNull();
//             return null;
//         }
//         String value = in.nextString();
//         String path = in.getPath();
// 
//         String[] components = splitComponents(value, path);
//         String family = components[0];
//         String style = components[1];
//         String sizeStr = components[2];
// 
//         FontWeight weight = extractWeight(style);
//         FontPosture posture = extractPosture(style);
//         double size = extractSize(sizeStr, path);
// 
//         return Font.font(family, weight, posture, size);
//     }
// 
//     private static String[] splitComponents(String value, String path) {
//         String[] font = value.split(",");
//         if (font.length < 3) {
//             throw InvalidFontException.missingComponent(value, path);
//         }
//         return font;
//     }
// 
//     private static FontWeight extractWeight(String style) {
//         for (String styleWord : style.split("\\s")) {
//             FontWeight weight = FontWeight.findByName(styleWord);
//             if (weight != null && weight != FontWeight.NORMAL) {
//                 return weight;
//             }
//         }
//         return FontWeight.NORMAL;
//     }
// 
//     private static FontPosture extractPosture(String style) {
//         for (String styleWord : style.split("\\s")) {
//             FontPosture posture = FontPosture.findByName(styleWord);
//             if (posture != null && posture != FontPosture.REGULAR) {
//                 return posture;
//             }
//         }
//         return FontPosture.REGULAR;
//     }
// 
//     private static double extractSize(String size, String path) {
//         try {
//             return Double.parseDouble(size);
//         } catch (NumberFormatException e) {
//             throw InvalidFontException.invalidSize(size, path, e);
//         }
//     }
// 
//     public static class InvalidFontException extends RuntimeException {
// 
//         InvalidFontException(String message) {
//             super(message);
//         }
// 
//         InvalidFontException(String message, Throwable cause) {
//             super(message, cause);
//         }
// 
//         static InvalidFontException missingComponent(String value, String path) {
//             return new InvalidFontException("Missing component in the font at path " + path + ", got '" + value + "'");
//         }
// 
//         static InvalidFontException invalidSize(String value, String path, Throwable cause) {
//             return new InvalidFontException("Invalid size for the font at path " + path + ", got '" + value + "'",
//                     cause);
//         }
//     }
// }


// Path: src/main/java/org/hildan/fxgson/factories/JavaFxExtraTypeAdapterFactory.java
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import org.hildan.fxgson.adapters.extras.ColorTypeAdapter;
import org.hildan.fxgson.adapters.extras.FontTypeAdapter;

package org.hildan.fxgson.factories;



/**
 * A {@link TypeAdapterFactory} for JavaFX's {@link Color} and {@link Font} classes.
 */
public class JavaFxExtraTypeAdapterFactory implements TypeAdapterFactory {

    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        Class<? super T> clazz = type.getRawType();

        if (Color.class.isAssignableFrom(clazz)) {
            return (TypeAdapter<T>) new ColorTypeAdapter();
        }

        if (Font.class.isAssignableFrom(clazz)) {
            return (TypeAdapter<T>) new FontTypeAdapter();