/*
 * Copyright (C) 2012 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 com.android.gallery3d.filtershow.filters;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;

import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation.StrokeData;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;

import java.util.Vector;

public class ImageFilterDraw extends ImageFilter {
    private static final String LOGTAG = "ImageFilterDraw";
    public final static byte SIMPLE_STYLE = 0;
    public final static byte BRUSH_STYLE_SPATTER = 1;
    public final static byte BRUSH_STYLE_MARKER = 2;
    public final static int NUMBER_OF_STYLES = 3;
    Bitmap mOverlayBitmap; // this accelerates interaction
    int mCachedStrokes = -1;
    int mCurrentStyle = 0;

    FilterDrawRepresentation mParameters = new FilterDrawRepresentation();

    public ImageFilterDraw() {
        mName = "Image Draw";
    }

    DrawStyle[] mDrawingsTypes = new DrawStyle[] {
            new SimpleDraw(),
            new Brush(R.drawable.brush_marker),
            new Brush(R.drawable.brush_spatter)
    };
    {
        for (int i = 0; i < mDrawingsTypes.length; i++) {
            mDrawingsTypes[i].setType((byte) i);
        }

    }

    @Override
    public FilterRepresentation getDefaultRepresentation() {
        return new FilterDrawRepresentation();
    }

    @Override
    public void useRepresentation(FilterRepresentation representation) {
        FilterDrawRepresentation parameters = (FilterDrawRepresentation) representation;
        mParameters = parameters;
    }

    public void setStyle(byte style) {
        mCurrentStyle = style % mDrawingsTypes.length;
    }

    public int getStyle() {
        return mCurrentStyle;
    }

    public static interface DrawStyle {
        public void setType(byte type);
        public void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
                int quality);
    }

    class SimpleDraw implements DrawStyle {
        byte mType;

        @Override
        public void setType(byte type) {
            mType = type;
        }

        @Override
        public void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
                int quality) {
            if (sd == null) {
                return;
            }
            if (sd.mPath == null) {
                return;
            }
            Paint paint = new Paint();

            paint.setStyle(Style.STROKE);
            paint.setColor(sd.mColor);
            paint.setStrokeWidth(toScrMatrix.mapRadius(sd.mRadius));

            // done this way because of a bug in path.transform(matrix)
            Path mCacheTransPath = new Path();
            mCacheTransPath.addPath(sd.mPath, toScrMatrix);

            canvas.drawPath(mCacheTransPath, paint);
        }
    }

    class Brush implements DrawStyle {
        int mBrushID;
        Bitmap mBrush;
        byte mType;

        public Brush(int brushID) {
            mBrushID = brushID;
        }
        public Bitmap getBrush() {
            if (mBrush == null) {
                BitmapFactory.Options opt = new BitmapFactory.Options();
                opt.inPreferredConfig = Bitmap.Config.ALPHA_8;
                mBrush = MasterImage.getImage().getImageLoader().decodeImage(mBrushID, opt);
                mBrush = mBrush.extractAlpha();
            }
            return mBrush;
        }

        @Override
        public void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
                int quality) {
            if (sd == null || sd.mPath == null) {
                return;
            }
            Paint paint = new Paint();
            paint.setStyle(Style.STROKE);
            paint.setAntiAlias(true);
            Path mCacheTransPath = new Path();
            mCacheTransPath.addPath(sd.mPath, toScrMatrix);
            draw(canvas, paint, sd.mColor, toScrMatrix.mapRadius(sd.mRadius) * 2,
                    mCacheTransPath);
        }

        public Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
        {
            Matrix m = new Matrix();
            m.setScale(dstWidth / (float) src.getWidth(), dstHeight / (float) src.getHeight());
            Bitmap result = Bitmap.createBitmap(dstWidth, dstHeight, src.getConfig());
            Canvas canvas = new Canvas(result);

            Paint paint = new Paint();
            paint.setFilterBitmap(filter);
            canvas.drawBitmap(src, m, paint);

            return result;

        }
        void draw(Canvas canvas, Paint paint, int color, float size, Path path) {
            PathMeasure mPathMeasure = new PathMeasure();
            float[] mPosition = new float[2];
            float[] mTan = new float[2];

            mPathMeasure.setPath(path, false);

            paint.setAntiAlias(true);
            paint.setColor(color);

            paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
            Bitmap brush;
            // done this way because of a bug in
            // Bitmap.createScaledBitmap(getBrush(),(int) size,(int) size,true);
            brush = createScaledBitmap(getBrush(), (int) size, (int) size, true);
            float len = mPathMeasure.getLength();
            float s2 = size / 2;
            float step = s2 / 8;
            for (float i = 0; i < len; i += step) {
                mPathMeasure.getPosTan(i, mPosition, mTan);
                //                canvas.drawCircle(pos[0], pos[1], size, paint);
                canvas.drawBitmap(brush, mPosition[0] - s2, mPosition[1] - s2, paint);
            }
        }

        @Override
        public void setType(byte type) {
            mType = type;
        }
    }

    void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
            int quality) {
        mDrawingsTypes[sd.mType].paint(sd, canvas, toScrMatrix, quality);
    }

    public void drawData(Canvas canvas, Matrix originalRotateToScreen, int quality) {
        Paint paint = new Paint();
        if (quality == ImagePreset.QUALITY_FINAL) {
            paint.setAntiAlias(true);
        }
        paint.setStyle(Style.STROKE);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(40);

        if (mParameters.getDrawing().isEmpty() && mParameters.getCurrentDrawing() == null) {
            return;
        }
        if (quality == ImagePreset.QUALITY_FINAL) {
            for (FilterDrawRepresentation.StrokeData strokeData : mParameters.getDrawing()) {
                paint(strokeData, canvas, originalRotateToScreen, quality);
            }
            return;
        }

        if (mOverlayBitmap == null ||
                mOverlayBitmap.getWidth() != canvas.getWidth() ||
                mOverlayBitmap.getHeight() != canvas.getHeight() ||
                mParameters.getDrawing().size() < mCachedStrokes) {

            mOverlayBitmap = Bitmap.createBitmap(
                    canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
            mCachedStrokes = 0;
        }

        if (mCachedStrokes < mParameters.getDrawing().size()) {
            fillBuffer(originalRotateToScreen);
        }
        canvas.drawBitmap(mOverlayBitmap, 0, 0, paint);

        StrokeData stroke = mParameters.getCurrentDrawing();
        if (stroke != null) {
            paint(stroke, canvas, originalRotateToScreen, quality);
        }
    }

    public void fillBuffer(Matrix originalRotateToScreen) {
        Canvas drawCache = new Canvas(mOverlayBitmap);
        Vector<FilterDrawRepresentation.StrokeData> v = mParameters.getDrawing();
        int n = v.size();

        for (int i = mCachedStrokes; i < n; i++) {
            paint(v.get(i), drawCache, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW);
        }
        mCachedStrokes = n;
    }

    public void draw(Canvas canvas, Matrix originalRotateToScreen) {
        for (FilterDrawRepresentation.StrokeData strokeData : mParameters.getDrawing()) {
            paint(strokeData, canvas, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW);
        }
        mDrawingsTypes[mCurrentStyle].paint(
                null, canvas, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW);
    }

    @Override
    public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        Matrix m = getOriginalToScreenMatrix(w, h);
        drawData(new Canvas(bitmap), m, quality);
        return bitmap;
    }

}
