package com.rubn.xsdvalidator.util;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.theme.lumo.LumoUtility;

public class Layout extends Div {

    private AlignItems alignItems;
    private AlignSelf alignSelf;
    private BoxSizing boxSizing;
    private Display display;
    private FlexDirection flexDirection;
    private FlexWrap flexWrap;
    private ColumnGap colGap;
    private RowGap rowGap;
    private GridColumns gridColumns;
    private JustifyContent justifyContent;
    private LineClamp lineClamp;
    private Overflow overflow;
    private Position position;

    public Layout(Component... components) {
        super(components);

        setDisplay(Display.FLEX);

    }

    public void setAlignItems(AlignItems alignItems) {
        if (this.alignItems != null) {
            removeClassNames(this.alignItems.getClassName());
        }
        addClassNames(alignItems.getClassName());
        this.alignItems = alignItems;
    }

    public void setAlignSelf(AlignSelf alignSelf) {
        if (this.alignSelf != null) {
            removeClassNames(this.alignSelf.getClassName());
        }
        addClassNames(alignSelf.getClassName());
        this.alignSelf = alignSelf;
    }

    public void setBoxSizing(BoxSizing boxSizing) {
        if (this.boxSizing != null) {
            removeClassNames(this.boxSizing.getClassName());
        }
        addClassNames(boxSizing.getClassName());
        this.boxSizing = boxSizing;
    }

    public void setDisplay(Display display) {
        if (this.display != null) {
            removeClassNames(this.display.getClassName());
        }
        addClassNames(display.getClassName());
        this.display = display;
    }

    public void setFlexDirection(FlexDirection flexDirection) {
        if (this.flexDirection != null) {
            removeClassNames(this.flexDirection.getClassName());
        }
        addClassNames(flexDirection.getClassName());
        this.flexDirection = flexDirection;
    }

    public void setFlexGrow() {
        addClassNames(LumoUtility.Flex.GROW);
    }

    public void setFlexGrow(Component... components) {
        for (Component component : components) {
            component.addClassNames(LumoUtility.Flex.GROW);
        }
    }

    public void setFlexWrap(FlexWrap flexWrap) {
        if (this.flexWrap != null) {
            removeClassNames(this.flexWrap.getClassName());
        }
        addClassNames(flexWrap.getClassName());
        this.flexWrap = flexWrap;
    }

    /**
     * Sets both the column (horizontal) and row (vertical) gap between components.
     */
    public void setGap(Gap gap) {
        setColumnGap(gap);
        setRowGap(gap);
    }

    /**
     * Sets the column (horizontal) gap between components.
     */
    public void setColumnGap(Gap gap) {
        removeColumnGap();
        this.addClassNames(gap.getColumnGap().getClassName());
        this.colGap = gap.getColumnGap();
    }

    /**
     * Sets the row (vertical) gap between components.
     */
    public void setRowGap(Gap gap) {
        removeRowGap();
        this.addClassNames(gap.getRowGap().getClassName());
        this.rowGap = gap.getRowGap();
    }

    /**
     * Removes the column (horizontal) gap between components.
     */
    public void removeColumnGap() {
        if (this.colGap != null) {
            this.removeClassName(this.colGap.getClassName());
        }
        this.colGap = null;
    }

    /**
     * Removes the row (vertical) gap between components.
     */
    public void removeRowGap() {
        if (this.rowGap != null) {
            this.removeClassName(this.rowGap.getClassName());
        }
        this.rowGap = null;
    }

    /**
     * Sets the default number of grid columns.
     */
    public void setColumns(GridColumns gridColumns) {
        if (this.gridColumns != null) {
            removeClassNames(this.gridColumns.getClassName());
        }
        addClassNames(gridColumns.getClassName());
        this.gridColumns = gridColumns;
    }

    /**
     * Sets the justify content property.
     */
    public void setJustifyContent(JustifyContent justifyContent) {
        if (this.justifyContent != null) {
            removeClassName(this.justifyContent.getClassName());
        }
        addClassNames(justifyContent.getClassName());
        this.justifyContent = justifyContent;
    }

    /**
     * Sets the line clamp property.
     */
    public void setLineClamp(LineClamp lineClamp) {
        if (this.lineClamp != null) {
            removeClassName(this.lineClamp.getClassName());
        }
        addClassNames(lineClamp.getClassName());
        this.lineClamp = lineClamp;
    }

    /**
     * Sets the overflow property.
     */
    public void setOverflow(Overflow overflow) {
        if (this.overflow != null) {
            removeClassNames(this.overflow.getClassName());
        }
        addClassNames(overflow.getClassName());
        this.overflow = overflow;
    }

    public void setPosition(Position position) {
        if (this.position != null) {
            this.removeClassName(this.position.getClassName());
        }
        addClassNames(position.getClassName());
        this.position = position;
    }

    public enum AlignItems {
        BASELINE(LumoUtility.AlignItems.BASELINE),
        CENTER(LumoUtility.AlignItems.CENTER),
        END(LumoUtility.AlignItems.END),
        START(LumoUtility.AlignItems.START),
        STRETCH(LumoUtility.AlignItems.STRETCH);

        private final String className;

        AlignItems(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum AlignSelf {
        AUTO(LumoUtility.AlignSelf.AUTO),
        BASELINE(LumoUtility.AlignSelf.BASELINE),
        CENTER(LumoUtility.AlignSelf.CENTER),
        END(LumoUtility.AlignSelf.END),
        START(LumoUtility.AlignSelf.START),
        STRETCH(LumoUtility.AlignSelf.STRETCH);

        private final String className;

        AlignSelf(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum BoxSizing {
        BORDER(LumoUtility.BoxSizing.BORDER),
        CONTENT(LumoUtility.BoxSizing.CONTENT);

        private final String className;

        BoxSizing(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum ColumnGap {
        PIXEL("gap-x-px"),
        XSMALL(LumoUtility.Gap.Column.XSMALL),
        SMALL(LumoUtility.Gap.Column.SMALL),
        MEDIUM(LumoUtility.Gap.Column.MEDIUM),
        LARGE(LumoUtility.Gap.Column.LARGE),
        XLARGE(LumoUtility.Gap.Column.XLARGE);

        private final String className;

        ColumnGap(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum ColumnSpan {
        COLUMN_SPAN_1(LumoUtility.Grid.Column.COLUMN_SPAN_1),
        COLUMN_SPAN_2(LumoUtility.Grid.Column.COLUMN_SPAN_2),
        COLUMN_SPAN_3(LumoUtility.Grid.Column.COLUMN_SPAN_3),
        COLUMN_SPAN_4(LumoUtility.Grid.Column.COLUMN_SPAN_4),
        COLUMN_SPAN_5(LumoUtility.Grid.Column.COLUMN_SPAN_5),
        COLUMN_SPAN_6(LumoUtility.Grid.Column.COLUMN_SPAN_6),
        COLUMN_SPAN_7(LumoUtility.Grid.Column.COLUMN_SPAN_7),
        COLUMN_SPAN_8(LumoUtility.Grid.Column.COLUMN_SPAN_8),
        COLUMN_SPAN_9(LumoUtility.Grid.Column.COLUMN_SPAN_9),
        COLUMN_SPAN_10(LumoUtility.Grid.Column.COLUMN_SPAN_10),
        COLUMN_SPAN_11(LumoUtility.Grid.Column.COLUMN_SPAN_11),
        COLUMN_SPAN_12(LumoUtility.Grid.Column.COLUMN_SPAN_12),
        COLUMN_SPAN_FULL("col-span-full");

        private final String className;

        ColumnSpan(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum Display {
        FLEX(LumoUtility.Display.FLEX),
        GRID(LumoUtility.Display.GRID);

        private final String className;

        Display(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum FlexDirection {
        COLUMN(LumoUtility.FlexDirection.COLUMN),
        COLUMN_REVERSE(LumoUtility.FlexDirection.COLUMN_REVERSE),
        ROW(LumoUtility.FlexDirection.ROW),
        ROW_REVERSE(LumoUtility.FlexDirection.ROW_REVERSE);

        private final String className;

        FlexDirection(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum FlexWrap {
        NOWRAP(LumoUtility.FlexWrap.NOWRAP),
        WRAP(LumoUtility.FlexWrap.WRAP),
        WRAP_REVERSE(LumoUtility.FlexWrap.WRAP_REVERSE);

        private final String className;

        FlexWrap(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum Gap {
        PIXEL("gap-px"),
        XSMALL(LumoUtility.Gap.XSMALL),
        SMALL(LumoUtility.Gap.SMALL),
        MEDIUM(LumoUtility.Gap.MEDIUM),
        LARGE(LumoUtility.Gap.LARGE),
        XLARGE(LumoUtility.Gap.XLARGE);

        private final String className;

        Gap(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }

        public ColumnGap getColumnGap() {
            return ColumnGap.valueOf(this.name());
        }

        public RowGap getRowGap() {
            return RowGap.valueOf(this.name());
        }
    }

    public enum GridColumns {
        COLUMNS_1(LumoUtility.Grid.Column.COLUMNS_1),
        COLUMNS_2(LumoUtility.Grid.Column.COLUMNS_2),
        COLUMNS_3(LumoUtility.Grid.Column.COLUMNS_3),
        COLUMNS_4(LumoUtility.Grid.Column.COLUMNS_4),
        COLUMNS_5(LumoUtility.Grid.Column.COLUMNS_5),
        COLUMNS_6(LumoUtility.Grid.Column.COLUMNS_6),
        COLUMNS_7(LumoUtility.Grid.Column.COLUMNS_7),
        COLUMNS_8(LumoUtility.Grid.Column.COLUMNS_8),
        COLUMNS_9(LumoUtility.Grid.Column.COLUMNS_9),
        COLUMNS_10(LumoUtility.Grid.Column.COLUMNS_10),
        COLUMNS_11(LumoUtility.Grid.Column.COLUMNS_11),
        COLUMNS_12(LumoUtility.Grid.Column.COLUMNS_12);

        private final String className;

        GridColumns(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }


    public enum LineClamp {
        LINE_CLAMP_1("line-clamp-1"),
        LINE_CLAMP_2("line-clamp-2"),
        LINE_CLAMP_3("line-clamp-3"),
        LINE_CLAMP_4("line-clamp-4");

        private final String className;

        LineClamp(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum RowGap {
        PIXEL("gap-y-px"),
        XSMALL(LumoUtility.Gap.Row.XSMALL),
        SMALL(LumoUtility.Gap.Row.SMALL),
        MEDIUM(LumoUtility.Gap.Row.MEDIUM),
        LARGE(LumoUtility.Gap.Row.LARGE),
        XLARGE(LumoUtility.Gap.Row.XLARGE);

        private final String className;

        RowGap(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum JustifyContent {
        AROUND(LumoUtility.JustifyContent.AROUND),
        BETWEEN(LumoUtility.JustifyContent.BETWEEN),
        CENTER(LumoUtility.JustifyContent.CENTER),
        END(LumoUtility.JustifyContent.END),
        EVENLY(LumoUtility.JustifyContent.EVENLY),
        START(LumoUtility.JustifyContent.START);

        private final String className;

        JustifyContent(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum Overflow {
        AUTO(LumoUtility.Overflow.AUTO),
        HIDDEN(LumoUtility.Overflow.HIDDEN);

        private final String className;

        Overflow(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

    public enum Position {
        ABSOLUTE(LumoUtility.Position.ABSOLUTE),
        FIXED(LumoUtility.Position.FIXED),
        RELATIVE(LumoUtility.Position.RELATIVE),
        STATIC(LumoUtility.Position.STATIC),
        STICKY(LumoUtility.Position.STICKY);

        private final String className;

        Position(String className) {
            this.className = className;
        }

        public String getClassName() {
            return this.className;
        }
    }

}
