1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.filtershow.category;
18
19import android.content.Context;
20import android.graphics.Bitmap;
21import android.graphics.BitmapFactory;
22import android.graphics.Canvas;
23import android.graphics.Matrix;
24import android.graphics.Paint;
25import android.graphics.Rect;
26import android.graphics.RectF;
27import android.util.Log;
28import android.widget.ArrayAdapter;
29import android.widget.ListAdapter;
30
31import com.android.gallery3d.R;
32import com.android.gallery3d.filtershow.FilterShowActivity;
33import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation;
34import com.android.gallery3d.filtershow.filters.FilterUserPresetRepresentation;
35import com.android.gallery3d.filtershow.pipeline.RenderingRequest;
36import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller;
37import com.android.gallery3d.filtershow.filters.FilterRepresentation;
38import com.android.gallery3d.filtershow.imageshow.MasterImage;
39import com.android.gallery3d.filtershow.pipeline.ImagePreset;
40
41public class Action implements RenderingRequestCaller {
42
43    private static final String LOGTAG = "Action";
44    private FilterRepresentation mRepresentation;
45    private String mName;
46    private Rect mImageFrame;
47    private Bitmap mImage;
48    private ArrayAdapter mAdapter;
49    public static final int FULL_VIEW = 0;
50    public static final int CROP_VIEW = 1;
51    public static final int ADD_ACTION = 2;
52    public static final int SPACER = 3;
53    private int mType = CROP_VIEW;
54    private Bitmap mPortraitImage;
55    private Bitmap mOverlayBitmap;
56    private FilterShowActivity mContext;
57    private boolean mCanBeRemoved = false;
58    private int mTextSize = 32;
59    private boolean mIsDoubleAction = false;
60
61    public Action(FilterShowActivity context, FilterRepresentation representation, int type,
62                  boolean canBeRemoved) {
63        this(context, representation, type);
64        mCanBeRemoved = canBeRemoved;
65        mTextSize = context.getResources().getDimensionPixelSize(
66                R.dimen.category_panel_text_size);
67    }
68
69    public Action(FilterShowActivity context, FilterRepresentation representation, int type) {
70        this(context, type);
71        setRepresentation(representation);
72    }
73
74    public Action(FilterShowActivity context, int type) {
75        mContext = context;
76        setType(type);
77        mContext.registerAction(this);
78    }
79
80    public Action(FilterShowActivity context, FilterRepresentation representation) {
81        this(context, representation, CROP_VIEW);
82    }
83
84    public boolean isDoubleAction() {
85        return mIsDoubleAction;
86    }
87
88    public void setIsDoubleAction(boolean value) {
89        mIsDoubleAction = value;
90    }
91
92    public boolean canBeRemoved() {
93        return mCanBeRemoved;
94    }
95
96    public int getType() {
97        return mType;
98    }
99
100    public FilterRepresentation getRepresentation() {
101        return mRepresentation;
102    }
103
104    public void setRepresentation(FilterRepresentation representation) {
105        mRepresentation = representation;
106        mName = representation.getName();
107    }
108
109    public String getName() {
110        return mName;
111    }
112
113    public void setName(String name) {
114        mName = name;
115    }
116
117    public void setImageFrame(Rect imageFrame, int orientation) {
118        if (mImageFrame != null && mImageFrame.equals(imageFrame)) {
119            return;
120        }
121        if (getType() == Action.ADD_ACTION) {
122            return;
123        }
124        Bitmap temp = MasterImage.getImage().getTemporaryThumbnailBitmap();
125        if (temp != null) {
126            mImage = temp;
127        }
128        Bitmap bitmap = MasterImage.getImage().getThumbnailBitmap();
129        if (bitmap != null) {
130            mImageFrame = imageFrame;
131            int w = mImageFrame.width();
132            int h = mImageFrame.height();
133            postNewIconRenderRequest(w, h);
134        }
135    }
136
137    public Bitmap getImage() {
138        return mImage;
139    }
140
141    public void setImage(Bitmap image) {
142        mImage = image;
143    }
144
145    public void setAdapter(ArrayAdapter adapter) {
146        mAdapter = adapter;
147    }
148
149    public void setType(int type) {
150        mType = type;
151    }
152
153    private void postNewIconRenderRequest(int w, int h) {
154        if (mRepresentation != null) {
155            ImagePreset preset = new ImagePreset();
156            preset.addFilter(mRepresentation);
157            RenderingRequest.postIconRequest(mContext, w, h, preset, this);
158        }
159    }
160
161    private void drawCenteredImage(Bitmap source, Bitmap destination, boolean scale) {
162        int minSide = Math.min(destination.getWidth(), destination.getHeight());
163        Matrix m = new Matrix();
164        float scaleFactor = minSide / (float) Math.min(source.getWidth(), source.getHeight());
165
166        float dx = (destination.getWidth() - source.getWidth() * scaleFactor) / 2.0f;
167        float dy = (destination.getHeight() - source.getHeight() * scaleFactor) / 2.0f;
168        if (mImageFrame.height() > mImageFrame.width()) {
169            // if portrait
170            dy -= mTextSize;
171        }
172        m.setScale(scaleFactor, scaleFactor);
173        m.postTranslate(dx, dy);
174        Canvas canvas = new Canvas(destination);
175        canvas.drawBitmap(source, m, new Paint(Paint.FILTER_BITMAP_FLAG));
176    }
177
178    @Override
179    public void available(RenderingRequest request) {
180        clearBitmap();
181        mImage = request.getBitmap();
182        if (mImage == null) {
183            mImageFrame = null;
184            return;
185        }
186        if (mRepresentation.getOverlayId() != 0 && mOverlayBitmap == null) {
187            mOverlayBitmap = BitmapFactory.decodeResource(
188                    mContext.getResources(),
189                    mRepresentation.getOverlayId());
190        }
191        if (mOverlayBitmap != null) {
192            if (getRepresentation().getFilterType() == FilterRepresentation.TYPE_BORDER) {
193                Canvas canvas = new Canvas(mImage);
194                canvas.drawBitmap(mOverlayBitmap, new Rect(0, 0, mOverlayBitmap.getWidth(), mOverlayBitmap.getHeight()),
195                        new Rect(0, 0, mImage.getWidth(), mImage.getHeight()), new Paint());
196            } else {
197                Canvas canvas = new Canvas(mImage);
198                canvas.drawARGB(128, 0, 0, 0);
199                drawCenteredImage(mOverlayBitmap, mImage, false);
200            }
201        }
202        if (mAdapter != null) {
203            mAdapter.notifyDataSetChanged();
204        }
205    }
206
207    public void setPortraitImage(Bitmap portraitImage) {
208        mPortraitImage = portraitImage;
209    }
210
211    public Bitmap getPortraitImage() {
212        return mPortraitImage;
213    }
214
215    public Bitmap getOverlayBitmap() {
216        return mOverlayBitmap;
217    }
218
219    public void setOverlayBitmap(Bitmap overlayBitmap) {
220        mOverlayBitmap = overlayBitmap;
221    }
222
223    public void clearBitmap() {
224        if (mImage != null
225                && mImage != MasterImage.getImage().getTemporaryThumbnailBitmap()) {
226            MasterImage.getImage().getBitmapCache().cache(mImage);
227        }
228        mImage = null;
229    }
230}
231