//	Contour - Android drawing teacher application
//	Copyright (C) 2014  Johannes Riedmann
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//	
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//	
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.

package com.j0h1.contour;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.j0h1.contour.R;
import com.j0h1.contour.database.ContourDatabase;
import com.j0h1.contour.pojo.ImagePojo;
import com.j0h1.contour.pojo.Player;
import com.j0h1.contour.utils.RESTConfig;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Window;

/**
 * Activity that is responsible for requesting a upload of the
 * session and image data to the server and show the user feedback of
 * the progress.
 * @author Johannes Riedmann
 *
 */
public class UploadLoadingScreenActivity extends Activity {
	
	private ProgressDialog progressDialog;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		
		new LoadViewTask().execute();
	}
	
	/**
	 * Background task that executes the session upload.
	 */
	private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
		@Override
		protected void onPreExecute() {
			// create and set up progress dialog
			progressDialog = new ProgressDialog(UploadLoadingScreenActivity.this);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			progressDialog.setTitle(getString(R.string.uploading) + "...");
			progressDialog
					.setMessage(getString(R.string.uploading_data_please_wait) + "...");
			progressDialog.setCancelable(false);
			progressDialog.setIndeterminate(true);
			progressDialog.show();
		}

		// the code to be executed in a background thread
		@Override
		protected Void doInBackground(Void... params) {			
			// get the current thread's token
			synchronized (this) {
				// get session data from local database
				ContourDatabase db = new ContourDatabase(getApplicationContext());
				final int trackId = db.getCurrentTrackId();
				final ArrayList<ImagePojo> customImageList = db.getCurrentCustomImageData();
				final ArrayList<ImagePojo> drawings = db.getDrawings();
				final ArrayList<ImagePojo> scoreImages = db.getScoreImages();
				final double score = db.getCurrentScore();
				final Player player = db.findPlayer();
				db.close();
				
				// start Volley request to persist data to server
		    	RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
		    	
		    	StringRequest request = new StringRequest(Request.Method.POST, 
		    			RESTConfig.BASE_URL + "session", 
		    			new Response.Listener<String>() {
							@Override
							public void onResponse(String response) {
								if (response.equals("success")) {									
									// clear local session and image data
									ContourDatabase db = new ContourDatabase(getApplicationContext());
									db.discardSession();
									db.close();
									
									// close progressDialog
									progressDialog.dismiss();
									
									// redirect to HighscoreActivity
									Intent intent = new Intent(UploadLoadingScreenActivity.this, 
											HighscoreActivity.class);
									startActivity(intent);
								}
							}
		    			},
		    			new Response.ErrorListener() {
							@Override
							public void onErrorResponse(VolleyError arg0) {
								// on error return to SessionFinishedActivity and do not remove session data								
								Intent intent = new Intent(UploadLoadingScreenActivity.this, 
										SessionFinishedActivity.class);
								intent.putExtra("error", "VolleyError");
								startActivity(intent);
							}    				
		    			}    		    		
				) {
		    		@Override
		    		protected Map<String, String> getParams() {
		    			// add session data as parameters to the post request
		    			Map<String, String> params = new HashMap<String, String>();
		    			params.put("trackId", "" + trackId);
		    			params.put("username", player.getPlayername());
		    			params.put("score", "" + score);
		    			
		    			// if it's a custom session, add original and edge data
	    				if (customImageList.size() == 2) {
	    					params.put("edgeData", customImageList.get(0).getData());
	    					params.put("originalData", customImageList.get(1).getData());
	    					params.put("imagename", customImageList.get(0).getImagename());
	    				}
		    			
		    			// add drawings
		    			for (int i = 0; i < drawings.size(); i++) {
		    				params.put("drawing" + drawings.get(i).getImageId(), drawings.get(i).getData());
		    			}
		    			
		    			// add scoreimages
		    			for (int i = 0; i < scoreImages.size(); i++) {
		    				params.put("scoreimage" + drawings.get(i).getImageId(), scoreImages.get(i).getData());
		    				params.put("score" + drawings.get(i).getImageId(), "" + scoreImages.get(i).getScore());
		    			}
		    			
		    			return params;
		    		}
		    	};
		    	
		    	// this RetryPolicy defines a default socket timeout of 20 seconds
		    	// if the data could not be uploaded in this time, the upload is aborted
		    	request.setRetryPolicy(new DefaultRetryPolicy(
		    		       (int) TimeUnit.SECONDS.toMillis(20), 0,
		    		       DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
		    	
		    	queue.add(request);
			}
			
			return null;
		}
		
		@Override
		protected void onProgressUpdate(Integer... values) {
			progressDialog.setProgress(values[0]);
		}
		
		@Override
		protected void onPostExecute(Void result) {			
		}
	}
	
	/**
	 * The activity handles the orientation changes itself, so on every orientation
	 * change (portrait to landscape and vice versa) this method is called.
	 */
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
    	super.onConfigurationChanged(newConfig);
    }

}
