/*
 * Copyright (c) 2013 by Gerrit Grunwald
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.hansolo.enzo.splitflap;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Dimension2D;
import javafx.scene.paint.Color;

import java.util.HashMap;


public class SplitFlapBuilder<B extends SplitFlapBuilder<B>> {
    private HashMap<String, Property> properties = new HashMap<>();


    // ******************** Constructors **************************************
    protected SplitFlapBuilder() {}


    // ******************** Methods *******************************************
    public static final SplitFlapBuilder create() {
        return new SplitFlapBuilder();
    }

    public final SplitFlapBuilder keepAspect(final boolean KEEP_ASPECT) {
        properties.put("keepAspect", new SimpleBooleanProperty(KEEP_ASPECT));
        return this;
    }

    public final SplitFlapBuilder flipTime(final double FLIP_TIME) {
        properties.put("flipTime", new SimpleDoubleProperty(FLIP_TIME));
        return this;
    }

    public final SplitFlapBuilder wordMode(final boolean WORD_MODE) {
        properties.put("wordMode", new SimpleBooleanProperty(WORD_MODE));
        return this;
    }

    public final SplitFlapBuilder withFixture(final boolean WITH_FIXTURE) {
        properties.put("withFixture", new SimpleBooleanProperty(WITH_FIXTURE));
        return this;
    }

    public final SplitFlapBuilder darkFixture(final boolean DARK_FIXTURE) {
        properties.put("darkFixture", new SimpleBooleanProperty(DARK_FIXTURE));
        return this;
    }

    public final SplitFlapBuilder squareFlaps(final boolean SQUARE_FLAPS) {
        properties.put("squareFlaps", new SimpleBooleanProperty(SQUARE_FLAPS));
        return this;
    }

    public final SplitFlapBuilder flapColor(final Color FLAP_COLOR) {
        properties.put("flapColor", new SimpleObjectProperty<>(FLAP_COLOR));
        return this;
    }

    public final SplitFlapBuilder textColor(final Color TEXT_COLOR) {
        properties.put("textColor", new SimpleObjectProperty<>(TEXT_COLOR));
        return this;
    }

    public final SplitFlapBuilder text(final String TEXT) {
        properties.put("text", new SimpleStringProperty(TEXT));
        return this;
    }

    public final SplitFlapBuilder selection(final String[] SELECTION) {
        properties.put("selection", new SimpleObjectProperty<>(SELECTION));
        return this;
    }

    public final B prefSize(final double WIDTH, final double HEIGHT) {
        properties.put("prefSize", new SimpleObjectProperty<>(new Dimension2D(WIDTH, HEIGHT)));
        return (B)this;
    }
    public final B minSize(final double WIDTH, final double HEIGHT) {
        properties.put("minSize", new SimpleObjectProperty<>(new Dimension2D(WIDTH, HEIGHT)));
        return (B)this;
    }
    public final B maxSize(final double WIDTH, final double HEIGHT) {
        properties.put("maxSize", new SimpleObjectProperty<>(new Dimension2D(WIDTH, HEIGHT)));
        return (B)this;
    }

    public final B prefWidth(final double PREF_WIDTH) {
        properties.put("prefWidth", new SimpleDoubleProperty(PREF_WIDTH));
        return (B)this;
    }
    public final B prefHeight(final double PREF_HEIGHT) {
        properties.put("prefHeight", new SimpleDoubleProperty(PREF_HEIGHT));
        return (B)this;
    }

    public final B minWidth(final double MIN_WIDTH) {
        properties.put("minWidth", new SimpleDoubleProperty(MIN_WIDTH));
        return (B)this;
    }
    public final B minHeight(final double MIN_HEIGHT) {
        properties.put("minHeight", new SimpleDoubleProperty(MIN_HEIGHT));
        return (B)this;
    }

    public final B maxWidth(final double MAX_WIDTH) {
        properties.put("maxWidth", new SimpleDoubleProperty(MAX_WIDTH));
        return (B)this;
    }
    public final B maxHeight(final double MAX_HEIGHT) {
        properties.put("maxHeight", new SimpleDoubleProperty(MAX_HEIGHT));
        return (B)this;
    }

    public final B scaleX(final double SCALE_X) {
        properties.put("scaleX", new SimpleDoubleProperty(SCALE_X));
        return (B)this;
    }
    public final B scaleY(final double SCALE_Y) {
        properties.put("scaleY", new SimpleDoubleProperty(SCALE_Y));
        return (B)this;
    }

    public final B layoutX(final double LAYOUT_X) {
        properties.put("layoutX", new SimpleDoubleProperty(LAYOUT_X));
        return (B)this;
    }
    public final B layoutY(final double LAYOUT_Y) {
        properties.put("layoutY", new SimpleDoubleProperty(LAYOUT_Y));
        return (B)this;
    }

    public final B translateX(final double TRANSLATE_X) {
        properties.put("translateX", new SimpleDoubleProperty(TRANSLATE_X));
        return (B)this;
    }
    public final B translateY(final double TRANSLATE_Y) {
        properties.put("translateY", new SimpleDoubleProperty(TRANSLATE_Y));
        return (B)this;
    }


    public final SplitFlap build() {
        final SplitFlap CONTROL;
        if (properties.containsKey("selection")) {
            if (properties.containsKey("text")) {
                CONTROL = new SplitFlap(((ObjectProperty<String[]>) properties.get("selection")).get(),
                                        ((StringProperty) properties.get("text")).get());
            } else {
                CONTROL = new SplitFlap(((ObjectProperty<String[]>) properties.get("selection")).get(),
                                        ((ObjectProperty<String[]>) properties.get("selection")).get()[0]);
            }
        } else {
            CONTROL = new SplitFlap();
        }
        for (String key : properties.keySet()) {
            if ("keepAspect".equals(key)) {
                CONTROL.setKeepAspect(((BooleanProperty) properties.get(key)).get());
            } else if ("flipTime".equals(key)) {
                CONTROL.setFlipTime(((DoubleProperty) properties.get(key)).get());
            } else if ("wordMode".equals(key)) {
                CONTROL.setWordMode(((BooleanProperty) properties.get(key)).get());
            } else if ("withFixture".equals(key)) {
                CONTROL.setWithFixture(((BooleanProperty) properties.get(key)).get());
            } else if ("darkFixture".equals(key)) {
                CONTROL.setDarkFixture(((BooleanProperty) properties.get(key)).get());
            } else if ("squareFlaps".equals(key)) {
                CONTROL.setSquareFlaps(((BooleanProperty) properties.get(key)).get());
            } else if ("flapColor".equals(key)) {
                CONTROL.setFlapColor(((ObjectProperty<Color>) properties.get(key)).get());
            } else if ("textColor".equals(key)) {
                CONTROL.setTextColor(((ObjectProperty<Color>) properties.get(key)).get());
            } else if ("text".equals(key)) {
                CONTROL.setText(((StringProperty) properties.get(key)).get());
            } else if ("selection".equals(key)) {
                CONTROL.setSelection(((ObjectProperty<String[]>) properties.get(key)).get());
            } else if ("prefSize".equals(key)) {
                Dimension2D dim = ((ObjectProperty<Dimension2D>) properties.get(key)).get();
                CONTROL.setPrefSize(dim.getWidth(), dim.getHeight());
            } else if("minSize".equals(key)) {
                Dimension2D dim = ((ObjectProperty<Dimension2D>) properties.get(key)).get();
                CONTROL.setPrefSize(dim.getWidth(), dim.getHeight());
            } else if("maxSize".equals(key)) {
                Dimension2D dim = ((ObjectProperty<Dimension2D>) properties.get(key)).get();
                CONTROL.setPrefSize(dim.getWidth(), dim.getHeight());
            } else if("prefWidth".equals(key)) {
                CONTROL.setPrefWidth(((DoubleProperty) properties.get(key)).get());
            } else if("prefHeight".equals(key)) {
                CONTROL.setPrefHeight(((DoubleProperty) properties.get(key)).get());
            } else if("minWidth".equals(key)) {
                CONTROL.setMinWidth(((DoubleProperty) properties.get(key)).get());
            } else if("minHeight".equals(key)) {
                CONTROL.setMinHeight(((DoubleProperty) properties.get(key)).get());
            } else if("maxWidth".equals(key)) {
                CONTROL.setMaxWidth(((DoubleProperty) properties.get(key)).get());
            } else if("maxHeight".equals(key)) {
                CONTROL.setMaxHeight(((DoubleProperty) properties.get(key)).get());
            } else if("scaleX".equals(key)) {
                CONTROL.setScaleX(((DoubleProperty) properties.get(key)).get());
            } else if("scaleY".equals(key)) {
                CONTROL.setScaleY(((DoubleProperty) properties.get(key)).get());
            } else if ("layoutX".equals(key)) {
                CONTROL.setLayoutX(((DoubleProperty) properties.get(key)).get());
            } else if ("layoutY".equals(key)) {
                CONTROL.setLayoutY(((DoubleProperty) properties.get(key)).get());
            } else if ("translateX".equals(key)) {
                CONTROL.setTranslateX(((DoubleProperty) properties.get(key)).get());
            } else if ("translateY".equals(key)) {
                CONTROL.setTranslateY(((DoubleProperty) properties.get(key)).get());
            }
        }

        return CONTROL;
    }
}
