/*
 * #%L
 * GwtMaterial
 * %%
 * Copyright (C) 2015 - 2017 GwtMaterialDesign
 * %%
 * 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.
 * #L%
 */
package gwt.material.design.client.ui;

import com.google.gwt.dom.client.Style.Unit;
import gwt.material.design.client.base.HasOverlayStyle;
import gwt.material.design.client.base.HasType;
import gwt.material.design.client.base.mixin.ColorsMixin;
import gwt.material.design.client.base.mixin.CssTypeMixin;
import gwt.material.design.client.base.mixin.OverlayStyleMixin;
import gwt.material.design.client.constants.Color;
import gwt.material.design.client.constants.CssName;
import gwt.material.design.client.constants.OverlayOption;
import gwt.material.design.client.constants.ProgressType;
import gwt.material.design.client.ui.html.Div;
import gwt.material.design.jquery.client.api.JQueryElement;

//@formatter:off

/**
 * Material Progress indicator to define intermediate and determinate progress bars
 * <h3>UiBinder Usage:</h3>
 * <p>
 * <pre>
 * {@code
 * // INDETERMINATE Type
 * <m:MaterialProgress type="INDETERMINATE" />
 *
 * // DETERMINATE Type
 * <m:MaterialProgress type="DETERMINATE" percent="80" />
 * }
 * </pre>
 *
 * @author kevzlou7979
 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#loader">Material Progress</a>
 * @see <a href="https://material.io/guidelines/components/progress-activity.html#">Material Design Specification</a>
 */
public class MaterialProgress extends Div implements HasType<ProgressType>, HasOverlayStyle {

    private double percent = 0;
    private Div fillContainer = new Div();

    private ColorsMixin<Div> fillColorMixin;
    private CssTypeMixin<ProgressType, MaterialProgress> typeMixin;
    private OverlayStyleMixin<MaterialDialog> overlayStyleMixin;

    public MaterialProgress() {
        super(CssName.PROGRESS);
        getElement().getStyle().setMargin(0, Unit.PX);
        add(fillContainer);
        setType(ProgressType.INDETERMINATE);
    }

    public MaterialProgress(ProgressType type) {
        this();
        setType(type);
    }

    public MaterialProgress(ProgressType type, Double percent) {
        this(type);
        setPercent(percent);
    }

    @Override
    public void setType(ProgressType type) {
        getTypeMixin().setType(type);
    }

    @Override
    public ProgressType getType() {
        return getTypeMixin().getType();
    }

    /**
     * Get progress width as percent unit
     */
    public double getPercent() {
        return percent;
    }

    /**
     * Set progress width as percent unit.
     * If percent is greater than 100 then reset the progress in the maximum value (100%)
     * If percent is less than 0 then reset the progress in the minimum value (0%)
     */
    public void setPercent(double percent) {

        if (percent > 100) {
            percent = 100;
        }

        if (percent < 0) {
            percent = 0;
        }

        this.percent = percent;
        fillContainer.getElement().getStyle().setWidth(percent, Unit.PCT);
    }

    @Override
    public void setOverlayOption(OverlayOption overlayOption) {
        getOverlayStyleMixin().setOverlayOption(overlayOption);
    }

    @Override
    public OverlayOption getOverlayOption() {
        return getOverlayStyleMixin().getOverlayOption();
    }

    @Override
    public void applyOverlayStyle(JQueryElement overlayElement) {
        getOverlayStyleMixin().applyOverlayStyle(overlayElement);
    }

    @Override
    public void resetOverlayStyle() {
        getOverlayStyleMixin().resetOverlayStyle();
    }

    /**
     * Get the progress bar color.
     */
    public Color getColor() {
        return getFillColorMixin().getBackgroundColor();
    }

    /**
     * Set the color of the progress bar.
     *
     * @param color String value of the color.
     */
    public void setColor(Color color) {
        getFillColorMixin().setBackgroundColor(color);
    }

    public Div getFillContainer() {
        return fillContainer;
    }

    protected ColorsMixin<Div> getFillColorMixin() {
        if (fillColorMixin == null) {
            fillColorMixin = new ColorsMixin<>(fillContainer);
        }
        return fillColorMixin;
    }

    protected CssTypeMixin<ProgressType, MaterialProgress> getTypeMixin() {
        if (typeMixin == null) {
            typeMixin = new CssTypeMixin<>(this, fillContainer);
        }
        return typeMixin;
    }

    protected OverlayStyleMixin<MaterialDialog> getOverlayStyleMixin() {
        if (overlayStyleMixin == null) {
            overlayStyleMixin = new OverlayStyleMixin(this);
        }
        return overlayStyleMixin;
    }
}