//	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.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

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.Volley;
import com.j0h1.contour.R;
import com.j0h1.contour.pojo.ImagePojo;
import com.j0h1.contour.pojo.ImageResponseList;
import com.j0h1.contour.pojo.Session;
import com.j0h1.contour.utils.RESTConfig;
import com.j0h1.contour.volley.SimpleXmlRequest;
import com.sun.jersey.core.util.Base64;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.OnChildClickListener;

/**
 * Dialog that contains additional information for a specific drawing
 * session.
 * @author Johannes Riedmann
 *
 */
public class SessionDetailsDialog extends Dialog {
	
	// dialog shows details of this session
	private Session session;	
	private String language;	
	private Toast toast;
	private Context context;

	public SessionDetailsDialog(Context context, Session session) {
		super(context);
		
		this.context = context;
		this.session = session;		
		language = context.getResources().getConfiguration().locale.getLanguage();
		
		setUpDialog();
		
		requestImagesOfSession();
	}
	
	/**
	 * Defines the resources/inflates layout of the SessionDetailsView
	 */
	@SuppressLint("SimpleDateFormat") 
	private void setUpDialog() {
		setContentView(R.layout.highscore_session_view);
		setTitle(context.getString(R.string.session_from));
		
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		// set session relevant data for the dialog
		TextView txtHighscoreSessionPlayer = (TextView) findViewById(R.id.txtHighscoreSessionPlayer);
		txtHighscoreSessionPlayer.setText(context.getString(R.string.player_title) 
				+ " " + session.getPlayer().getPlayername());
		
		TextView txtHighscoreSessionDate = (TextView) findViewById(R.id.txtHighscoreSessionDate);
		txtHighscoreSessionDate.setText(context.getString(R.string.date_title) 
				+ " " + formatter.format(new Date(session.getDate())));
		
		TextView txtHighscoreSessionScore = (TextView) findViewById(R.id.txtHighscoreSessionScore);
		txtHighscoreSessionScore.setText(context.getString(R.string.score_title) 
				+ " " + session.getScore());
		
		Button btnHighscoreSessionClose = (Button) findViewById(R.id.btnHighscoreSessionClose);
		btnHighscoreSessionClose.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				dismiss();
			}
		});
	}
	
	/**
	 * Requests the metadata for the images persisted for the current session.
	 */
	private void requestImagesOfSession() {
		RequestQueue rq = Volley.newRequestQueue(context.getApplicationContext());
		
		SimpleXmlRequest<ImageResponseList> request = new SimpleXmlRequest<ImageResponseList>(
				Request.Method.GET,
				RESTConfig.BASE_URL + "images/session/" + session.getSessionId() + "/language/" + language,
				ImageResponseList.class,
				new Response.Listener<ImageResponseList>() {
					@Override
					public void onResponse(ImageResponseList response) {
						if (response.getList() != null) {
							populateImageList(response.getList());							
						} else {
							prepareToast(context.getString(R.string.session_details_not_found));
							toast.show();
						}
					}
				}, new Response.ErrorListener() {
					@Override
					public void onErrorResponse(VolleyError error) {
						prepareToast(context.getString(R.string.connection_lost));
						toast.show();
					}
				});
		
		rq.add(request);
	}
	
	/**
	 * Populates the ExpandableListView with the image metadata requested previously.
	 * @param images Images retrieved from the previous request.
	 */
	private void populateImageList(ArrayList<ImagePojo> images) {
		ExpandableListView elvHighscoreSessionImageList = 
				(ExpandableListView) findViewById(R.id.elvHighscoreSessionImageList);
		
		// set child data for each image header, which is defined by the 
		// image_download_titles array (see res/values/strings.xml)
		SessionDetailsExpandableListAdapter adapter = 
				new SessionDetailsExpandableListAdapter(context, 
						images, 
						context.getResources().getStringArray(R.array.image_download_titles));
		
		elvHighscoreSessionImageList.setAdapter(adapter);
		
		// set an OnClickListener for the children - depending on which child is clicked, 
		// request the image data afterwards
		elvHighscoreSessionImageList.setOnChildClickListener(new OnChildClickListener() {
			@Override
			public boolean onChildClick(
					ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				// define which image was selected by the user
				ImagePojo selectedImage = (ImagePojo) parent
						.getExpandableListAdapter().getGroup(groupPosition);
				
				if (childPosition == 0) {
					// request original image
					requestImageData(session, selectedImage, 0);
				} else if (childPosition == 1) {
					// request edge image
					requestImageData(session, selectedImage, 1);
				} else if (childPosition == 2) {
					// request drawing with sessionId / imageId
					requestImageData(session, selectedImage, 2);
				} else if (childPosition == 3) {
					// request score image with sessionId / imageId
					requestImageData(session, selectedImage, 3);
				}
				
				return false;
			}										
		});
	}
	
	/**
	 * Request image data for a specific image, in a specific session or a given type.
	 * @param session	The session the image was drawn in.
	 * @param image		The desired image.
	 * @param type		Defines the type of image the user requests
	 * 					0 = original image; 1 = edge image; 
	 * 					2 = drawing; 		3 = score image
	 */
	private void requestImageData(Session session, final ImagePojo image, int type) {
		RequestQueue rq = Volley.newRequestQueue(context.getApplicationContext());
		
		// start Dialog for image and show ProgressBar to the user
		final Dialog imageDialog = new Dialog(context);
		imageDialog.setContentView(R.layout.image_dialog);
		imageDialog.setTitle(image.getImagename());
		
		final ProgressBar pbImageLoading = (ProgressBar) imageDialog.findViewById(R.id.pbImageLoading);
		pbImageLoading.setVisibility(View.VISIBLE);
		
		imageDialog.show();
		
		SimpleXmlRequest<ImagePojo> request = new SimpleXmlRequest<ImagePojo>(
				Request.Method.GET,
				RESTConfig.BASE_URL + "images/image/" + image.getImageId() 
									+ "/session/" + session.getSessionId() 
									+ "/type/" + type,
				ImagePojo.class,
				new Response.Listener<ImagePojo>() {
					@Override
					public void onResponse(ImagePojo response) {
						if (response.getData() != null) {
							// if data was received, set the data to the Image object
							// passed to this method and start an image prompt to show it
							image.setData(response.getData());
							
							// set an OnClickListener for the dialog to disappear
							ImageView dialogImageView = (ImageView) imageDialog.findViewById(R.id.ivImageDialogData);
							dialogImageView.setOnClickListener(new View.OnClickListener() {
								@Override
								public void onClick(View v) {
									imageDialog.dismiss();
								}			
							});
							
							// decode the base64 data from the server and convert it into a Drawable
							byte[] imageBytes = Base64.decode(image.getData());		
							Bitmap imageBitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);		
							Drawable imageDrawable = new BitmapDrawable(context.getResources(), imageBitmap);
							
							// hide ProgressBar immediately before image is displayed
							pbImageLoading.setVisibility(View.GONE);							
							
							// attach the Drawable to the ImageView in the imageDialog and show it
							dialogImageView.setImageDrawable(imageDrawable);
						} else {
							prepareToast(context.getString(R.string.image_data_not_found));
							toast.show();
						}
					}
				}, 
				new Response.ErrorListener() {
					@Override
					public void onErrorResponse(VolleyError error) {
						prepareToast(context.getString(R.string.connection_lost));
						toast.show();
					}
				});
		
		rq.add(request);
	}
	
	@SuppressLint("ShowToast") 
	private void prepareToast(String message) {
		if (toast != null) {
    		toast.cancel();
    	}
    	toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
	}

}
