package com.epam.training.taskmanager.helper;

import android.os.Handler;

import com.epam.training.taskmanager.os.AsyncTask;
import com.epam.training.taskmanager.processing.Processor;
import com.epam.training.taskmanager.source.DataSource;


/**
 * Created by IstiN on 15.10.2014.
 */
public class DataManager {

    public static final boolean IS_ASYNC_TASK = true;

    public static interface Callback<Result> {
        void onDataLoadStart();
        void onDone(Result data);
        void onError(Exception e);
    }

    public static <ProcessingResult, DataSourceResult, Params> void
        loadData(
            final Callback<ProcessingResult> callback,
            final Params params,
            final DataSource<DataSourceResult, Params> dataSource,
            final Processor<ProcessingResult, DataSourceResult> processor) {
        if (callback == null) {
            throw new IllegalArgumentException("callback can't be null");
        }
        if (IS_ASYNC_TASK) {
            executeInAsyncTask(callback, params, dataSource);
        } else {
            executeInThread(callback, params, dataSource, processor);
        }
    }

    private static <ProcessingResult, DataSourceResult, Params> void executeInAsyncTask(final Callback<ProcessingResult> callback, Params params, final DataSource<DataSourceResult, Params> dataSource) {
        new AsyncTask<Params, Void, ProcessingResult>() {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                callback.onDataLoadStart();
            }

            @Override
            protected void onPostExecute(ProcessingResult processingResult) {
                super.onPostExecute(processingResult);
                callback.onDone(processingResult);
            }

            @Override
            protected ProcessingResult doInBackground(Params... params) throws Exception {
                return (ProcessingResult) dataSource.getResult((Params) params);
            }

            @Override
            protected void onPostException(Exception e) {
                callback.onError(e);
            }

        }.execute(params);
    }

    private static <ProcessingResult, DataSourceResult, Params> void executeInThread(final Callback<ProcessingResult> callback, final Params params, final DataSource<DataSourceResult, Params> dataSource, final Processor<ProcessingResult, DataSourceResult> processor) {
        final Handler handler = new Handler();
        callback.onDataLoadStart();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final DataSourceResult result = dataSource.getResult(params);
                    final ProcessingResult processingResult = processor.process(result);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onDone(processingResult);
                        }
                    });
                } catch (final Exception e) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onError(e);
                        }
                    });
                }
            }
        }).start();
    }

}

@@ -433,32 +433,33 @@
 ataLoadStart();%0A
+%0A
         void onD
@@ -476,16 +476,17 @@
  data);%0A
+%0A
         
@@ -587,20 +587,16 @@
 s%3E void%0A
-    
     load
@@ -601,16 +601,16 @@
 adData(%0A
+
         
@@ -1037,16 +1037,27 @@
 taSource
+, processor
 );%0A     
@@ -1354,16 +1354,79 @@
 taSource
+, final Processor%3CProcessingResult, DataSourceResult%3E processor
 ) %7B%0A    
@@ -1997,33 +1997,43 @@
     
-return (Processing
+DataSourceResult dataSource
 Result
-)
+ =
  dat
@@ -2054,23 +2054,77 @@
 ult(
-(P
+p
 arams
-) params
+%5B0%5D);%0A                return processor.process(dataSourceResult
 );%0A 

FIX bug