package org.geuz.onelab;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Fragment;
import android.graphics.Bitmap;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

public class ModelFragment extends Fragment{

	private Gmsh _gmsh;
	private mGLSurfaceView _glView;
	private TextView _progress;
	private LinearLayout _progressLayout;
	private LinearLayout _controlBarLayout;
	private GestureDetector _gestureDetector;
	private Timer _animation;
	private Handler _hideDelay;
	private SeekBar _animationStepper;

	final Runnable hideControlsRunnable = new Runnable() {public void run() {hideControlBar();}};

	public static ModelFragment newInstance(Gmsh g) {
		ModelFragment fragment = new ModelFragment();
		Bundle bundle = new Bundle();
		bundle.putParcelable("Gmsh", g);
		fragment.setArguments(bundle);
        return fragment;
    }
	
	public ModelFragment() {
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		_gmsh = getArguments().getParcelable("Gmsh");
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragment_model, container, false);
		RelativeLayout glViewLayout = (RelativeLayout)rootView.findViewById(R.id.glViewLayout);
		GLESRender renderer = new GLESRender(_gmsh);
		_glView = new mGLSurfaceView(glViewLayout.getContext(), renderer);
		_glView.setEGLContextClientVersion(1);
		_glView.setRenderer(renderer);
		_glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
		_glView.requestRender();
		_hideDelay = new Handler();
		_gestureDetector = new GestureDetector(getActivity(), new OnGestureListener() {
			public boolean onSingleTapUp(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
			public void onShowPress(MotionEvent e) {} // UNUSED Auto-generated method stub
			public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } // UNUSED Auto-generated method stub
			public void onLongPress(MotionEvent e) {} // UNUSED Auto-generated method stub
			public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } // UNUSED Auto-generated method stub
			public boolean onDown(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
		});
		_gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
			public boolean onSingleTapConfirmed(MotionEvent e) {
				if(View.VISIBLE == _controlBarLayout.getVisibility())
					hideControlBar();
				else
					showControlBar();
				return true;
			}
			public boolean onDoubleTapEvent(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
			public boolean onDoubleTap(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
		});
		_glView.setOnTouchListener(new View.OnTouchListener() {
			
			public boolean onTouch(View v, MotionEvent event) {
				return _gestureDetector.onTouchEvent(event);
			}
		});
		glViewLayout.addView(_glView);
		_progressLayout = new LinearLayout(container.getContext());
		ProgressBar bar = new ProgressBar(container.getContext());
		bar.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				_progress.setAlpha((_progress.getAlpha() > 0)? 0 : 1);
			}
		});
		_progressLayout.addView(bar);
		_progress = new TextView(container.getContext());
		_progressLayout.setAlpha(0);
		_progressLayout.setGravity(Gravity.CENTER);
		_progressLayout.addView(_progress);
		RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
			    RelativeLayout.LayoutParams.WRAP_CONTENT, 
			    RelativeLayout.LayoutParams.WRAP_CONTENT);
		layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		glViewLayout.addView(_progressLayout, layoutParams);
		_controlBarLayout = (LinearLayout) getActivity().getLayoutInflater().inflate(R.layout.control_bar, null);
		final ImageButton prevButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPrev);
		final ImageButton playPauseButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPlay);
		final ImageButton nextButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlNext);
		_animationStepper = (SeekBar)_controlBarLayout.findViewById(R.id.controlStepper);
		_animationStepper.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
			
			public void onStopTrackingTouch(SeekBar seekBar) {} // UNUSED Auto-generated method stub
			public void onStartTrackingTouch(SeekBar seekBar) {} // UNUSED Auto-generated method stub
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				if(fromUser) {
					postDelay();
					_gmsh.setAnimation(progress);
					requestRender();
				}
			}
		});
		_controlBarLayout.setEnabled(false);
		playPauseButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				postDelay();
				if(((ImageButton)v).getContentDescription().equals("play")) {
					((ImageButton)v).setContentDescription("pause");
					((ImageButton)v).setImageResource(android.R.drawable.ic_media_pause);
					_animationStepper.setMax(_gmsh.numberOfAnimation()-1);
		    		_animation = new Timer();
		    		_animation.schedule(new TimerTask() {
		    			public void run()  {
		    				_animationStepper.setProgress(_gmsh.animationNext());
		    				requestRender();
		    			} }, 0, 500);
		    		prevButton.setEnabled(false);
		    		nextButton.setEnabled(false);
				}
				else {
					((ImageButton)v).setContentDescription("play");
					((ImageButton)v).setImageResource(android.R.drawable.ic_media_play);
					_animation.cancel();
					prevButton.setEnabled(true);
					nextButton.setEnabled(true);
				}
			}
		});
		nextButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				postDelay();
				_animationStepper.setProgress(_gmsh.animationNext());
		    	requestRender();
			}
		});
		prevButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				postDelay();
				_animationStepper.setProgress(_gmsh.animationPrev());
		    	requestRender();
			}
		});
		layoutParams = new RelativeLayout.LayoutParams(
			    RelativeLayout.LayoutParams.MATCH_PARENT, 
			    RelativeLayout.LayoutParams.WRAP_CONTENT);
		layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		glViewLayout.addView(_controlBarLayout, layoutParams);
		this._controlBarLayout.setVisibility(View.INVISIBLE);
		return rootView;
	}
	public void postDelay(int delay) {
		_hideDelay.removeCallbacks(hideControlsRunnable);
		_hideDelay.postDelayed(hideControlsRunnable, delay);
	}
	public void postDelay() {
		this.postDelay(6000);
	}
	public void showControlBar() {
		if(getActivity() == null || ((MainActivity)getActivity()).isComputing() || !_gmsh.haveAnimation()) return;
		_controlBarLayout.setEnabled(true);
		_animationStepper.setMax(_gmsh.numberOfAnimation()-1);
		this.postDelay();
		Animation bottomUp = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
		_controlBarLayout.setVisibility(View.VISIBLE);
		_controlBarLayout.startAnimation(bottomUp);
	}
	public void hideControlBar() {
		if(getActivity() == null || View.INVISIBLE == _controlBarLayout.getVisibility()) return;
		_hideDelay.removeCallbacks(hideControlsRunnable);
		Animation bottomDown = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
		_controlBarLayout.startAnimation(bottomDown);
		_controlBarLayout.setVisibility(View.INVISIBLE);
		
	}
	public void showProgress(String progress) {
		_progressLayout.setAlpha(1);
		_progress.setText(progress);
	}
	public void hideProgress() {
		_progressLayout.setAlpha(0);
		_progress.setText("");
	}
	public void requestRender() {
		_glView.requestRender();
	}
	public void takeScreenshot(File out) {
		Bitmap screenshot = _glView.getScreenshot();
		try {
			FileOutputStream f = new FileOutputStream(out);
			screenshot.compress(Bitmap.CompressFormat.PNG, 85, f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		finally {
			_glView.setDrawingCacheEnabled(false);
		}
	}
}
