package com.aviary.android.feather.effects;
import org.json.JSONException;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.aviary.android.feather.R;
import com.aviary.android.feather.library.filters.EnhanceFilter;
import com.aviary.android.feather.library.filters.EnhanceFilter.Types;
import com.aviary.android.feather.library.filters.FilterLoaderFactory;
import com.aviary.android.feather.library.filters.FilterLoaderFactory.Filters;
import com.aviary.android.feather.library.moa.Moa;
import com.aviary.android.feather.library.moa.MoaActionList;
import com.aviary.android.feather.library.services.EffectContext;
import com.aviary.android.feather.library.utils.BitmapUtils;
import com.aviary.android.feather.library.utils.SystemUtils;
import com.aviary.android.feather.widget.ImageButtonRadioGroup;
import com.aviary.android.feather.widget.ImageButtonRadioGroup.OnCheckedChangeListener;
// TODO: Auto-generated Javadoc
/**
* The Class EnhanceEffectPanel.
*/
public class EnhanceEffectPanel extends AbstractOptionPanel implements OnCheckedChangeListener {
/** current rendering task */
private RenderTask mCurrentTask;
private Filters mFilterType;
volatile boolean mIsRendering = false;
boolean enableFastPreview = false;
MoaActionList mActions = null;
/**
* Instantiates a new enhance effect panel.
*
* @param context
* the context
* @param type
* the type
*/
public EnhanceEffectPanel( EffectContext context, Filters type ) {
super( context );
mFilterType = type;
}
@Override
public void onCreate( Bitmap bitmap ) {
super.onCreate( bitmap );
// well, it's better to have the big progress here
// enableFastPreview = Constants.getFastPreviewEnabled();
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractEffectPanel#onActivate()
*/
@Override
public void onActivate() {
super.onActivate();
mPreview = BitmapUtils.copy( mBitmap, Config.ARGB_8888 );
ImageButtonRadioGroup radio = (ImageButtonRadioGroup) getOptionView().findViewById( R.id.radio );
radio.setOnCheckedChangeListener( this );
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractOptionPanel#generateOptionView(android.view.LayoutInflater,
* android.view.ViewGroup)
*/
@Override
protected ViewGroup generateOptionView( LayoutInflater inflater, ViewGroup parent ) {
return (ViewGroup) inflater.inflate( R.layout.feather_enhance_panel, parent, false );
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractEffectPanel#onBackPressed()
*/
@Override
public boolean onBackPressed() {
mLogger.info( "onBackPressed" );
killCurrentTask();
return super.onBackPressed();
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractEffectPanel#onCancelled()
*/
@Override
public void onCancelled() {
killCurrentTask();
mIsRendering = false;
super.onCancelled();
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractEffectPanel#onCancel()
*/
@Override
public boolean onCancel() {
killCurrentTask();
return super.onCancel();
}
/**
* Kill current task.
*/
private void killCurrentTask() {
if ( mCurrentTask != null ) {
synchronized ( mCurrentTask ) {
mCurrentTask.cancel( true );
mCurrentTask.renderFilter.stop();
onProgressEnd();
}
mIsRendering = false;
mCurrentTask = null;
}
}
@Override
protected void onProgressEnd() {
if ( !enableFastPreview ) {
super.onProgressModalEnd();
} else {
super.onProgressEnd();
}
}
@Override
protected void onProgressStart() {
if ( !enableFastPreview ) {
super.onProgressModalStart();
} else {
super.onProgressStart();
}
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractEffectPanel#getIsChanged()
*/
@Override
public boolean getIsChanged() {
return super.getIsChanged() || mIsRendering == true;
}
/**
* The Class RenderTask.
*/
class RenderTask extends AsyncTask<Types, Void, Bitmap> {
/** The m error. */
String mError;
/** The render filter. */
volatile EnhanceFilter renderFilter;
/**
* Instantiates a new render task.
*/
public RenderTask() {
renderFilter = (EnhanceFilter) FilterLoaderFactory.get( mFilterType );
mError = null;
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
onProgressStart();
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Bitmap doInBackground( Types... params ) {
if ( isCancelled() ) return null;
Bitmap result = null;
mIsRendering = true;
Types type = params[0];
renderFilter.setType( type );
try {
result = renderFilter.execute( mBitmap, mPreview, 1, 1 );
mActions = renderFilter.getActions();
} catch ( JSONException e ) {
e.printStackTrace();
mError = e.getMessage();
return null;
}
if ( isCancelled() ) return null;
return result;
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute( Bitmap result ) {
super.onPostExecute( result );
if ( !isActive() ) return;
onProgressEnd();
if ( isCancelled() ) return;
if ( result != null ) {
if ( SystemUtils.isHoneyComb() ) {
Moa.notifyPixelsChanged( mPreview );
}
onPreviewChanged( mPreview, true );
} else {
if ( mError != null ) {
onGenericError( mError );
}
}
mIsRendering = false;
mCurrentTask = null;
}
@Override
protected void onCancelled() {
renderFilter.stop();
super.onCancelled();
}
}
/*
* (non-Javadoc)
*
* @see
* com.aviary.android.feather.widget.ImageButtonRadioGroup.OnCheckedChangeListener#onCheckedChanged(com.aviary.android.feather
* .widget.ImageButtonRadioGroup, int, boolean)
*/
@Override
public void onCheckedChanged( ImageButtonRadioGroup group, int checkedId, boolean isChecked ) {
mLogger.info( "onCheckedChange: " + checkedId );
if ( !isActive() || !isEnabled() ) return;
Types type = null;
killCurrentTask();
if ( checkedId == R.id.button1 ) {
type = Types.AUTOENHANCE;
} else if ( checkedId == R.id.button2 ) {
type = Types.NIGHTENHANCE;
} else if ( checkedId == R.id.button3 ) {
type = Types.BACKLIGHT;
} else if ( checkedId == R.id.button4 ) {
type = Types.LABCORRECT;
}
if ( !isChecked ) {
// restore the original image
BitmapUtils.copy( mBitmap, mPreview );
onPreviewChanged( mPreview, true );
setIsChanged( false );
mActions = null;
} else {
if ( type != null ) {
mCurrentTask = new RenderTask();
mCurrentTask.execute( type );
}
}
}
/*
* (non-Javadoc)
*
* @see com.aviary.android.feather.effects.AbstractEffectPanel#onGenerateResult()
*/
@Override
protected void onGenerateResult() {
if ( mIsRendering ) {
GenerateResultTask task = new GenerateResultTask();
task.execute();
} else {
onComplete( mPreview, mActions );
}
}
/**
* The Class GenerateResultTask.
*/
class GenerateResultTask extends AsyncTask<Void, Void, Void> {
/** The m progress. */
ProgressDialog mProgress = new ProgressDialog( getContext().getBaseContext() );
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgress.setTitle( getContext().getBaseContext().getString( R.string.feather_loading_title ) );
mProgress.setMessage( getContext().getBaseContext().getString( R.string.effect_loading_message ) );
mProgress.setIndeterminate( true );
mProgress.setCancelable( false );
mProgress.show();
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Void doInBackground( Void... params ) {
mLogger.info( "GenerateResultTask::doInBackground", mIsRendering );
while ( mIsRendering ) {
// mLogger.log( "waiting...." );
}
return null;
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute( Void result ) {
super.onPostExecute( result );
mLogger.info( "GenerateResultTask::onPostExecute" );
if ( getContext().getBaseActivity().isFinishing() ) return;
if ( mProgress.isShowing() ) mProgress.dismiss();
onComplete( mPreview, mActions );
}
}
}