/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 android.hardware.display;

import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.MathUtils;

import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;

/**
 * BrightnessCorrection encapsulates a correction to the brightness, without comitting to the
 * actual correction scheme.
 * It is used by the BrightnessConfiguration, which maps context (e.g. the foreground app's package
 * name and category) to corrections that need to be applied to the brightness within that context.
 * Corrections are currently done by the app that has the top activity of the focused stack, either
 * by its package name, or (if its package name is not mapped to any correction) by its category.
 *
 * @hide
 */
@SystemApi
@TestApi
public final class BrightnessCorrection implements Parcelable {

    private static final int SCALE_AND_TRANSLATE_LOG = 1;

    private static final String TAG_SCALE_AND_TRANSLATE_LOG = "scale-and-translate-log";

    private BrightnessCorrectionImplementation mImplementation;

    // Parcelable classes must be final, and protected methods are not allowed in APIs, so we can't
    // make this class abstract and use composition instead of inheritence.
    private BrightnessCorrection(BrightnessCorrectionImplementation implementation) {
        mImplementation = implementation;
    }

    /**
     * Creates a BrightnessCorrection that given {@code brightness}, corrects it to be
     * {@code exp(scale * ln(brightness) + translate)}.
     *
     * @param scale
     *      How much to scale the log (base e) brightness.
     * @param translate
     *      How much to translate the log (base e) brightness.
     *
     * @return A BrightnessCorrection that given {@code brightness}, corrects it to be
     * {@code exp(scale * ln(brightness) + translate)}.
     *
     * @throws IllegalArgumentException
     *      - scale or translate are NaN.
     */
    @NonNull
    public static BrightnessCorrection createScaleAndTranslateLog(float scale, float translate) {
        BrightnessCorrectionImplementation implementation =
                new ScaleAndTranslateLog(scale, translate);
        return new BrightnessCorrection(implementation);
    }

    /**
     * Applies the brightness correction to a given brightness.
     *
     * @param brightness
     *      The brightness.
     *
     * @return The corrected brightness.
     */
    @FloatRange(from = 0.0)
    public float apply(@FloatRange(from = 0.0) float brightness) {
        return mImplementation.apply(brightness);
    }

    /**
     * Returns a string representation.
     *
     * @return A string representation.
     */
    public String toString() {
        return mImplementation.toString();
    }


    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof BrightnessCorrection)) {
            return false;
        }
        BrightnessCorrection other = (BrightnessCorrection) o;
        return other.mImplementation.equals(mImplementation);
    }

    @Override
    public int hashCode() {
        return mImplementation.hashCode();
    }

    public static final Creator<BrightnessCorrection> CREATOR =
            new Creator<BrightnessCorrection>() {
                public BrightnessCorrection createFromParcel(Parcel in) {
                    final int type = in.readInt();
                    switch (type) {
                        case SCALE_AND_TRANSLATE_LOG:
                            return ScaleAndTranslateLog.readFromParcel(in);
                    }
                    return null;
                }

                public BrightnessCorrection[] newArray(int size) {
                    return new BrightnessCorrection[size];
                }
            };

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        mImplementation.writeToParcel(dest);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Writes the correction to an XML serializer.
     *
     * @param serializer
     *      The XML serializer.
     *
     * @hide
     */
    public void saveToXml(XmlSerializer serializer) throws IOException {
        mImplementation.saveToXml(serializer);
    }

    /**
     * Read a correction from an XML parser.
     *
     * @param parser
     *      The XML parser.
     *
     * @throws IOException
     *      The parser failed to read the XML file.
     * @throws XmlPullParserException
     *      The parser failed to parse the XML file.
     *
     * @hide
     */
    public static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException,
            XmlPullParserException {
        final int depth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, depth)) {
            if (TAG_SCALE_AND_TRANSLATE_LOG.equals(parser.getName())) {
                return ScaleAndTranslateLog.loadFromXml(parser);
            }
        }
        return null;
    }

    private static float loadFloatFromXml(XmlPullParser parser, String attribute) {
        final String string = parser.getAttributeValue(null, attribute);
        try {
            return Float.parseFloat(string);
        } catch (NullPointerException | NumberFormatException e) {
            return Float.NaN;
        }
    }

    private interface BrightnessCorrectionImplementation {
        float apply(float brightness);
        String toString();
        void writeToParcel(Parcel dest);
        void saveToXml(XmlSerializer serializer) throws IOException;
        // Package-private static methods:
        // static BrightnessCorrection readFromParcel(Parcel in);
        // static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException,
        //      XmlPullParserException;
    }

    /**
     * A BrightnessCorrection that given {@code brightness}, corrects it to be
     * {@code exp(scale * ln(brightness) + translate)}.
     */
    private static class ScaleAndTranslateLog implements BrightnessCorrectionImplementation {
        private static final float MIN_SCALE = 0.5f;
        private static final float MAX_SCALE = 2.0f;
        private static final float MIN_TRANSLATE = -0.6f;
        private static final float MAX_TRANSLATE = 0.7f;

        private static final String ATTR_SCALE = "scale";
        private static final String ATTR_TRANSLATE = "translate";

        private final float mScale;
        private final float mTranslate;

        ScaleAndTranslateLog(float scale, float translate) {
            if (Float.isNaN(scale) || Float.isNaN(translate)) {
                throw new IllegalArgumentException("scale and translate must be numbers");
            }
            mScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
            mTranslate = MathUtils.constrain(translate, MIN_TRANSLATE, MAX_TRANSLATE);
        }

        @Override
        public float apply(float brightness) {
            return MathUtils.exp(mScale * MathUtils.log(brightness) + mTranslate);
        }

        @Override
        public String toString() {
            return "ScaleAndTranslateLog(" + mScale + ", " + mTranslate + ")";
        }

        @Override
        public boolean equals(Object o) {
            if (o == this) {
                return true;
            }
            if (!(o instanceof ScaleAndTranslateLog)) {
                return false;
            }
            ScaleAndTranslateLog other = (ScaleAndTranslateLog) o;
            return other.mScale == mScale && other.mTranslate == mTranslate;
        }

        @Override
        public int hashCode() {
            int result = 1;
            result = result * 31 + Float.hashCode(mScale);
            result = result * 31 + Float.hashCode(mTranslate);
            return result;
        }

        @Override
        public void writeToParcel(Parcel dest) {
            dest.writeInt(SCALE_AND_TRANSLATE_LOG);
            dest.writeFloat(mScale);
            dest.writeFloat(mTranslate);
        }

        @Override
        public void saveToXml(XmlSerializer serializer) throws IOException {
            serializer.startTag(null, TAG_SCALE_AND_TRANSLATE_LOG);
            serializer.attribute(null, ATTR_SCALE, Float.toString(mScale));
            serializer.attribute(null, ATTR_TRANSLATE, Float.toString(mTranslate));
            serializer.endTag(null, TAG_SCALE_AND_TRANSLATE_LOG);
        }

        static BrightnessCorrection readFromParcel(Parcel in) {
            float scale = in.readFloat();
            float translate = in.readFloat();
            return BrightnessCorrection.createScaleAndTranslateLog(scale, translate);
        }

        static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException,
                XmlPullParserException {
            final float scale = loadFloatFromXml(parser, ATTR_SCALE);
            final float translate = loadFloatFromXml(parser, ATTR_TRANSLATE);
            return BrightnessCorrection.createScaleAndTranslateLog(scale, translate);
        }
    }
}
