package com.lemenzo.gallery.editor;

/** Pure-Java recommendation engine for local one-tap enhancement. */
public final class AutoEnhanceAnalyzer {
    public static final class Recommendation {
        public final float brightness, contrast, saturation, warmth, exposure, tint, highlights, shadows, sharpness;
        Recommendation(float brightness, float contrast, float saturation, float warmth, float exposure,
                float tint, float highlights, float shadows, float sharpness) {
            this.brightness=brightness; this.contrast=contrast; this.saturation=saturation; this.warmth=warmth;
            this.exposure=exposure; this.tint=tint; this.highlights=highlights; this.shadows=shadows; this.sharpness=sharpness;
        }
    }

    private AutoEnhanceAnalyzer() {}

    public static Recommendation recommend(int[] histogram, long samples, double avgR, double avgG, double avgB, double avgChroma) {
        if (histogram == null || histogram.length != 256 || samples <= 0)
            return new Recommendation(0f,0f,1f,0f,0f,0f,0f,0f,0f);
        int p10=percentile(histogram,samples,.10), p50=percentile(histogram,samples,.50), p90=percentile(histogram,samples,.90), p98=percentile(histogram,samples,.98);
        float median=p50/255f;
        float range=Math.max(.02f,(p90-p10)/255f);
        float exposure=clamp((float)(Math.log(Math.max(.08,.48/Math.max(.08,median)))/Math.log(2.0))*.55f,-.38f,.38f);
        float brightness=clamp((.48f-median)*.14f,-.08f,.08f);
        float contrast=clamp((.68f-range)*.45f,-.12f,.26f);
        float shadows=p10<34?clamp((34-p10)/100f,0f,.24f):0f;
        float highlights=p98>238?-clamp((p98-238)/65f,0f,.20f):(p90<185?.05f:0f);
        float saturation=clamp(1.04f+(float)Math.max(0,30.0-avgChroma)/300f,1.0f,1.14f);
        double mean=Math.max(1.0,(avgR+avgG+avgB)/3.0);
        float warmth=clamp((float)((avgB-avgR)/mean)*.20f,-.16f,.16f);
        float tint=clamp((float)((((avgR+avgB)/2.0)-avgG)/mean)*.14f,-.12f,.12f);
        float sharpness=range<.55f?.14f:.08f;
        return new Recommendation(brightness,contrast,saturation,warmth,exposure,tint,highlights,shadows,sharpness);
    }

    private static int percentile(int[] h,long total,double fraction){long target=Math.max(1L,(long)Math.ceil(total*fraction)),sum=0;for(int i=0;i<h.length;i++){sum+=h[i];if(sum>=target)return i;}return 255;}
    private static float clamp(float v,float lo,float hi){return Math.max(lo,Math.min(hi,v));}
}
