public class MainActivity extends ActionBarActivity implements
		NavigationDrawerFragment.NavigationDrawerCallbacks {

	/**
	 * Fragment managing the behaviors, interactions and presentation of the
	 * navigation drawer.
	 */
	private NavigationDrawerFragment mNavigationDrawerFragment;
	
	/**
	 * Used to store information during application restart due to configuration
	 * changes
	 */
	private RetainedFragment dataFragment;

	/**
	 * Simulator object
	 */
	private Simulator simulator;
	
	/**
	 * Returns the simulator object
	 * @return
	 */
	public Simulator getSimulator(){
		return simulator;
	}
	
	/**
	 * Browser object
	 */
	private XWalkView mXwalkView;
	private XWalkView mXwalkViewOrbit;
	private boolean loadBrowser;
	private boolean loadBrowserOrbit;
	/**
	 * Returns the simulator object
	 * @return
	 */
	public XWalkView getBrowser(){
		return mXwalkView;
	}
	public XWalkView getBrowserOrbit(){
		return mXwalkViewOrbit;
	}
	public boolean getLoadBrowserFlag(){
		return loadBrowser;
	}
	public void resetLoadBrowserFlag(){
		loadBrowser = false;
	}
	public void raiseLoadBrowserFlag(){
		loadBrowser = true;
	}
	public boolean getLoadBrowserFlagOrbit(){
		return loadBrowserOrbit;
	}
	public void resetLoadBrowserFlagOrbit(){
		loadBrowserOrbit = false;
	}
	public void raiseLoadBrowserFlagOrbit(){
		loadBrowserOrbit = true;
	}
	
    public boolean flag_show_welcome = false;
    
    private ProgressBar browserProgressBar = null;
    private FrameLayout browserProgressLayout = null;
    public void setBrowserProgressBar(ProgressBar bar, FrameLayout fr){
    	browserProgressLayout = fr;
    	browserProgressBar = bar;
    }
    public void resetBrowserProgressBar(){
    	browserProgressLayout = null;
    	browserProgressBar = null;
    }
    public void setBrowserProgressValue(int progr){
    	if(browserProgressLayout!=null && browserProgressBar!=null){
	    	browserProgressBar.setProgress(progr);
	    	if(progr<10000){
	    		browserProgressLayout.setVisibility(View.VISIBLE);
	    	}else{
	    		Animation fadeOut = new AlphaAnimation(1.00f, 0.00f);
                fadeOut.setDuration(1500);
                fadeOut.setAnimationListener(new AnimationListener() {
                    public void onAnimationStart(Animation animation) {}
                    public void onAnimationRepeat(Animation animation) {}
                    public void onAnimationEnd(Animation animation) {
                    	browserProgressLayout.setVisibility(View.GONE);
                    }
                });

                browserProgressLayout.startAnimation(fadeOut);
	    		
	    	}
    	}
    }
    
    
    private ProgressBar browserProgressBarOrbit = null;
    private FrameLayout browserProgressLayoutOrbit = null;
    public void setBrowserProgressBarOrbit(ProgressBar bar, FrameLayout fr){
    	browserProgressLayoutOrbit = fr;
    	browserProgressBarOrbit = bar;
    }
    public void resetBrowserProgressBarOrbit(){
    	browserProgressLayoutOrbit = null;
    	browserProgressBarOrbit = null;
    }
    public void setBrowserProgressValueOrbit(int progr){
    	if(browserProgressLayoutOrbit!=null && browserProgressBarOrbit!=null){
	    	browserProgressBarOrbit.setProgress(progr);
	    	if(progr<10000){
	    		browserProgressLayoutOrbit.setVisibility(View.VISIBLE);
	    	}else{
	    		Animation fadeOut = new AlphaAnimation(1.00f, 0.00f);
                fadeOut.setDuration(1500);
                fadeOut.setAnimationListener(new AnimationListener() {
                    public void onAnimationStart(Animation animation) {}
                    public void onAnimationRepeat(Animation animation) {}
                    public void onAnimationEnd(Animation animation) {
                    	browserProgressLayoutOrbit.setVisibility(View.GONE);
                    }
                });

                browserProgressLayoutOrbit.startAnimation(fadeOut);
	    		
	    	}
    	}
    }

    private ProgressBar browserProgressBarMap = null;
    private FrameLayout browserProgressLayoutMap = null;
    public void setBrowserProgressBarMap(ProgressBar bar, FrameLayout fr){
    	browserProgressLayoutMap = fr;
    	browserProgressBarMap = bar;
    }
    public void resetBrowserProgressBarMap(){
    	browserProgressLayoutMap = null;
    	browserProgressBarMap = null;
    }
    public void setBrowserProgressValueMap(int progr){
    	if(browserProgressLayoutMap!=null && browserProgressBarMap!=null){
	    	browserProgressBarMap.setProgress(progr);
	    	if(progr<10000){
	    		browserProgressLayoutMap.setVisibility(View.VISIBLE);
	    	}else{
	    		Animation fadeOut = new AlphaAnimation(1.00f, 0.00f);
                fadeOut.setDuration(1500);
                fadeOut.setAnimationListener(new AnimationListener() {
                    public void onAnimationStart(Animation animation) {}
                    public void onAnimationRepeat(Animation animation) {}
                    public void onAnimationEnd(Animation animation) {
                    	browserProgressLayoutMap.setVisibility(View.GONE);
                    }
                });

                browserProgressLayoutMap.startAnimation(fadeOut);
	    		
	    	}
    	}
    }
    
    //Temporal storing of the user missions for the upgrading of the database
    public ArrayList<UserMission> userMissions;
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//start_time = System.nanoTime(); 
		
		//Install Orekit default files if not installed yet
		userMissions = new ArrayList<UserMission>();
		Installer.installApkData(this);
		
		//Initialize Orekit with the data files
		OrekitInit.init(Installer.getOrekitDataRoot(this));
		
		//Configure application window
		//requestWindowFeature(Window.FEATURE_PROGRESS);
		setContentView(R.layout.activity_main);
		//setProgressBarVisibility(true);
		
		// find the retained fragment on activity restarts
        FragmentManager fm = getFragmentManager();
        dataFragment = (RetainedFragment) fm.findFragmentByTag("data");

        // create the fragment and data the first time
        if (dataFragment == null) {
        	((StavorApplication)getApplication()).modelViewId = R.id.menu_views_ref_frame_xyz;
        	((StavorApplication)getApplication()).modelOrbitViewId = R.id.menu_orbviews_free;
			((StavorApplication)getApplication()).follow_sc = R.id.menu_mapviews_free;
        	((StavorApplication)getApplication()).zoom = 1;
        	((StavorApplication)getApplication()).lon = (float)0.0;
        	((StavorApplication)getApplication()).lat = (float)0.0;
            // add the fragment
            dataFragment = new RetainedFragment();
            fm.beginTransaction().add(dataFragment, "data").commit();
            
            Simulator simu = new Simulator(this);
	    	
            ReaderDbHelper db_help_tmp;
            SQLiteDatabase db_tmp;
            db_help_tmp = Installer.installApkDatabase(this);
            db_tmp = db_help_tmp.getWritableDatabase();
            
            ((StavorApplication)getApplication()).jsInterface = new WebAppInterface(this, simu.getSimulationResults());
            
            dataFragment.setData(
            		simu,
            		db_help_tmp,
            		db_tmp,
            		Parameters.Hud.start_panel_open
            		);
            
            RatingSystem.verify(this);
        }
        
        // the data is available in dataFragment.getData()
        this.simulator = dataFragment.getSim();
        //this.simulator.reconstruct(this);
        
        //Update javascriptInterface
        ((StavorApplication)getApplication()).jsInterface.reconstruct(this, simulator.getSimulationResults());
        //XGGDEBUG: NullPointer dans cette ligne au dessus quand on ferme l'application
        
        mXwalkView = new XWalkView(this.getApplicationContext(), this);
		//mXwalkView.setBackgroundResource(R.color.black);
        mXwalkView.setBackgroundColor(0x00000000);
        mXwalkView.setResourceClient(new MyResourceClient(mXwalkView));
        mXwalkView.setUIClient(new MyUIClient(mXwalkView));
        mXwalkView.clearCache(true);
    	
    	//Orbit browser
        mXwalkViewOrbit = new XWalkView(this.getApplicationContext(), this);
		//mXwalkView.setBackgroundResource(R.color.black);
        mXwalkViewOrbit.setBackgroundColor(0x00000000);
        mXwalkViewOrbit.setResourceClient(new MyResourceClient(mXwalkViewOrbit));
        mXwalkViewOrbit.setUIClient(new MyUIClient(mXwalkViewOrbit));
        mXwalkViewOrbit.clearCache(true);
    	
    	((StavorApplication)getApplication()).jsInterface = new WebAppInterface(this, simulator.getSimulationResults());
    	mXwalkView.addJavascriptInterface(((StavorApplication)getApplication()).jsInterface, "Android");
    	mXwalkViewOrbit.addJavascriptInterface(((StavorApplication)getApplication()).jsInterface, "Android");
    	
    	mXwalkView.load(Parameters.Web.STARTING_PAGE,null);
    	mXwalkViewOrbit.load(Parameters.Web.STARTING_PAGE_ORBIT,null);
    	
    	resetLoadBrowserFlag();
    	resetLoadBrowserFlagOrbit();
        
		//Install the Missions database if not installed yet and store database objects
		((StavorApplication)getApplication()).db_help = dataFragment.getDbHelp();
		((StavorApplication)getApplication()).db = dataFragment.getDb();

		hud_panel_open = dataFragment.getHudPanelOpen();
        
        // NAVIGATION
		mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
				.findFragmentById(R.id.navigation_drawer);
		
		//((StavorApplication)getApplication()).mTitle = getTitle();

		// Set up the drawer.
		mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
				(DrawerLayout) findViewById(R.id.drawer_layout));
		
		restoreActionBar();
	}

	@Override
	public void onNavigationDrawerItemSelected(int position) {
		//Reset flag to not start playing when the browser has to reload.
		if(simulator!=null)
			simulator.resetTemporaryPause();
		// update the main content by replacing fragments
		FragmentManager fragmentManager = getFragmentManager();
		if(position==0){// selection of tabs content
			fragmentManager
			.beginTransaction()
			.replace(R.id.container,
					SimulatorFragment.newInstance(position + 1)).commit();
		}else if(position==1){
			fragmentManager
			.beginTransaction()
			.replace(R.id.container,
					HudFragment.newInstance(position + 1)).commit();
		}else if(position==2){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsBasicFragment.newInstance(position +1)).commit();
		}else if(position==3){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsExtraFragment.newInstance(position +1)).commit();
		}else if(position==4){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsMeasuresFragment.newInstance(position +1)).commit();
		}else if(position==5){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsModelsFragment.newInstance(position +1)).commit();
		}else if(position==6){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		OrbitFragment.newInstance(position +1)).commit();
		}else if(position==7){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsOrbitFragment.newInstance(position +1)).commit();
		}else if(position==8){
			fragmentManager
			.beginTransaction()
			.replace(R.id.container,
					MapFragment.newInstance(position + 1)).commit();
		}else if(position==9){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsCoverageFragment.newInstance(position +1)).commit();
		}else if(position==10){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, 
	        		StationsFragment.newInstance(position +1)).commit();
		}else if(position==11){
			// Display the fragment as the main content.
	        fragmentManager    
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsGeneralMapFragment.newInstance(position +1)).commit();
		}else if(position==12){
			// Display the fragment as the main content.
	        fragmentManager    
	        .beginTransaction()
	        .replace(R.id.container, 
	        		SettingsGeneralFragment.newInstance(position +1)).commit();
		}else if(position==13){
			// Display the fragment as the main content.
	        fragmentManager
	        .beginTransaction()
	        .replace(R.id.container, TestFragment.newInstance(position + 1)).commit();
		}else{
			
		}
	}

	/**
	 * Updates the title of the section
	 */
	public void onSectionAttached(int number) {
		((StavorApplication)getApplication()).currentSection = number;
		switch (number) {
		case 1:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section1);
			break;
		case 2:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section2);
			break;
		case 3:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section3);
			break;
		case 4:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section4);
			break;
		case 5:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section5);
			break;
		case 6:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section6);
			break;
		case 7:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section7);
			break;
		case 8:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section8);
			break;
		case 9:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section9);
			break;
		case 10:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section10);
			break;
		case 11:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section11);
			break;
		case 12:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section12);
			break;
		case 13:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section13);
			break;
		case 14:
			((StavorApplication)getApplication()).mTitle = getString(R.string.title_section14);
			break;
		}
	}
    
	public void restoreActionBar() {
		ActionBar actionBar = getSupportActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
		actionBar.setDisplayShowTitleEnabled(true);
		actionBar.setTitle(((StavorApplication)getApplication()).mTitle);
		//actionBar.setIcon(R.drawable.simulator_s);
		//getSupportActionBar().setDisplayShowHomeEnabled(true);
	}
	
	private ShareActionProvider mShareActionProvider;
	
	private void launchMarket() {

        
	    Uri uri = Uri.parse("market://details?id=" + getPackageName());
	    Intent myAppLinkToMarket = new Intent(Intent.ACTION_VIEW, uri);
	    try {
	        startActivity(myAppLinkToMarket);
	    } catch (ActivityNotFoundException e) {
	        Toast.makeText(this, " unable to find market app", Toast.LENGTH_LONG).show();
	    }
	}


	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		//actionBarMenu = menu;
		//currentSection = currentSection;
		if (!mNavigationDrawerFragment.isDrawerOpen()) {
			// Only show items in the action bar relevant to this screen
			// if the drawer is not showing. Otherwise, let the drawer
			// decide what to show in the action bar.
			getMenuInflater().inflate(R.menu.main, menu);
			
			// Locate MenuItem with ShareActionProvider
		    MenuItem item = menu.findItem(R.id.menu_item_share);
		    //mShareActionProvider = (ShareActionProvider) item.getActionProvider(); 
		    mShareActionProvider = (ShareActionProvider)
		            MenuItemCompat.getActionProvider(item);
		    
		    Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_TEXT,"https://play.google.com/store/apps/details?id=cs.si.stavor");
            shareIntent.setType("text/plain");
            mShareActionProvider.setShareIntent(shareIntent); 
		    
			restoreActionBar();
			return true;
		}
		
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		if (!mNavigationDrawerFragment.isDrawerOpen()) {
			// Only show items in the action bar relevant to this screen
			// if the drawer is not showing. Otherwise, let the drawer
			// decide what to show in the action bar.
			if(((StavorApplication)getApplication()).currentSection==1){
				MenuItem item = menu.findItem(R.id.action_simulator);
				//item.setVisible(false);
				item.setIcon(R.drawable.ab_simulator);
			}else if(((StavorApplication)getApplication()).currentSection==2){
				MenuItem item = menu.findItem(R.id.action_attitude);
				//item.setVisible(false);
				item.setIcon(R.drawable.ab_attitude);
			}else if(((StavorApplication)getApplication()).currentSection==7){
				MenuItem item = menu.findItem(R.id.action_orbit);
				//item.setVisible(false);
				item.setIcon(R.drawable.ab_orbit);
			}else if(((StavorApplication)getApplication()).currentSection==9){
				MenuItem item = menu.findItem(R.id.action_map);
				//item.setVisible(false);
				item.setIcon(R.drawable.ab_map);
			}
			supportInvalidateOptionsMenu();
			return true;
		}
		return super.onCreateOptionsMenu(menu);
	}
	
	public void refreshActionBarIcons(){
		supportInvalidateOptionsMenu();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_about) {
			showAbout();
			return true;
		}else if (id == R.id.action_simulator && ((StavorApplication)getApplication()).currentSection!=1) {
			showSection(0);
			return true;
		}else if (id == R.id.action_attitude && ((StavorApplication)getApplication()).currentSection!=2) {
			showSection(1);
			return true;
		}else if (id == R.id.action_orbit && ((StavorApplication)getApplication()).currentSection!=7) {
			showSection(6);
			return true;
		}else if (id == R.id.action_map && ((StavorApplication)getApplication()).currentSection!=9) {
			showSection(8);
			return true;
		}else if (id == R.id.menu_item_rate) {
			launchMarket();
		}else if (id == R.id.menu_item_tutorial) {
			String key1 = getString(R.string.pref_key_guide_visualization);
			String key2 = getString(R.string.pref_key_guide_simulator);
			SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
			sharedPref.edit()
					.putBoolean(key1, true)
					.putBoolean(key2, true).commit();
		}
		/*if (id == R.id.action_reset_conf) {
			resetUserConfigShowDialog();
			return true;
		}
		if (id == R.id.action_reset_db) {
			resetMissionsDbShowDialog();
			return true;
		}*/
		return super.onOptionsItemSelected(item);
	}

	/**
	 * Start the About activity
	 */
	public void showAbout() {
		Intent myIntent = new Intent(MainActivity.this, AboutActivity.class);
		MainActivity.this.startActivity(myIntent);
	}
	
	/**
	 * Starts the Mission editor activity in create mode
	 */
	public void showMissionCreator() {
		Intent myIntent = new Intent(MainActivity.this, MissionActivity.class);
		MainActivity.this.startActivity(myIntent);
	}
	
	/**
	 * Starts the Mission editor activity in edit mode
	 */
	public void showMissionEditor(MissionAndId mission){
		Intent myIntent = new Intent(MainActivity.this, MissionActivity.class);
		Bundle b = new Bundle();
		b.putSerializable("MISSION",mission);
		myIntent.putExtras(b);
		MainActivity.this.startActivity(myIntent);
	}
	
	/**
	 * Starts the Station editor activity in create mode
	 */
	public void showStationCreator() {
		Intent myIntent = new Intent(MainActivity.this, StationActivity.class);
		MainActivity.this.startActivity(myIntent);
	}
	
	/**
	 * Starts the Station editor activity in edit mode
	 */
	public void showStationEditor(StationAndId station){
		Intent myIntent = new Intent(MainActivity.this, StationActivity.class);
		Bundle b = new Bundle();
		b.putSerializable("STATION",station);
		myIntent.putExtras(b);
		MainActivity.this.startActivity(myIntent);
	}

	/**
	 * GoTo specified section of the navigation menu
	 * @param sel
	 */
	public void showSection(final int sel) {
		runOnUiThread( new Runnable() {
			public void run() {    
				mNavigationDrawerFragment.select(sel);
				onSectionAttached(sel+1);
				restoreActionBar();
	        }
		});
	}
	
	/**
	 * GoTo previously selected section of the navigation menu
	 */
	public void showSection() {
		showSection(mNavigationDrawerFragment.getSelectedPosition());
	}
	
    private Toast toast;
    private long lastBackPressTime = 0;


    @Override
    public void onBackPressed() {
    	if (!mNavigationDrawerFragment.isDrawerOpen()) {//If the navigation menu is not opened
	    	int sel = mNavigationDrawerFragment.getSelectedPosition();
	    	if(sel==7){//If it is currently in a configuration section, goto Hud
	    		showSection(6);
	    	}else if (sel>1 && sel<6){//If it is in Hud, goto simulator screen
	    		showSection(1);
	    	}else if (sel>8 && sel<12){//If it is in Hud, goto simulator screen
	    		showSection(8);
	    	}else if (sel==1 || sel==6 || sel==8 || sel==12){//If it is in Hud, goto simulator screen
	    		showSection(0);
	    	}else if (sel==0){//If it is in Simulator, warn user before exit
		    	if (this.lastBackPressTime < System.currentTimeMillis() - 4000) {//Wait some time for confirmation
		    		toast = Toast.makeText(this, getString(R.string.app_exit_prevent_message), 4000);
		    		toast.show();
		    		this.lastBackPressTime = System.currentTimeMillis();
		    	} else {//Exit application
		    		if (toast != null) {
		    			toast.cancel();
		    		}
		    		super.onBackPressed();
		    	}
	    	}
    	}else{//If the navigation menu is open, close it
    		showSection();	
	    }
    }
    
    /**
     * Displays the Welcome dialog
     */
    public void showWelcomeMessage() {
		if(Parameters.App.show_orekit_data_installation_message){
	        DialogFragment newFragment = new WelcomeDialogFragment();
	        newFragment.show(getFragmentManager(), "welcome");
		}
    }
    
    /**
     * Displays an error dialog
     * @param message
     * @param canIgnore
     */
    public void showErrorDialog(String message, boolean canIgnore) {
    	DialogFragment newFragment = ErrorDialogFragment.newInstance(message, canIgnore);
    	newFragment.setCancelable(false);
    	newFragment.show(getFragmentManager(), "error");
    }
    
    
    /*public void showTutorialSimulator(){
    	String key = getString(R.string.pref_key_tutorial_simulator);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_simulator);
	    	String message = getString(R.string.tutorial_message_simulator);
	    	showTutorialDialog(key, title, message);
    	}
    	if(flag_show_welcome){
    		flag_show_welcome=false;
			showWelcomeMessage();
    	}
    }*/
    /*
    public void showTutorialDisplay(){
    	String key = getString(R.string.pref_key_tutorial_display);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_display);
	    	String message = getString(R.string.tutorial_message_display);
	    	showTutorialDialog(key, title, message);
    	}
    }
    public void showTutorialOrbit(){
    	String key = getString(R.string.pref_key_tutorial_orbit);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_orbit);
	    	String message = getString(R.string.tutorial_message_orbit);
	    	showTutorialDialog(key, title, message);
    	}
    }
    public void showTutorialConfig(){
    	String key = getString(R.string.pref_key_tutorial_config);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_config);
	    	String message = getString(R.string.tutorial_message_config);
	    	showTutorialDialog(key, title, message);
    	}
    }
	public void showTutorialMap(){
    	String key = getString(R.string.pref_key_tutorial_map);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_map);
	    	String message = getString(R.string.tutorial_message_map);
	    	showTutorialDialog(key, title, message);
    	}
    }
    public void showTutorialStations(){
    	String key = getString(R.string.pref_key_tutorial_stations);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_stations);
	    	String message = getString(R.string.tutorial_message_stations);
	    	showTutorialDialog(key, title, message);
    	}
    }
    public void showTutorialCoverage(){
    	String key = getString(R.string.pref_key_tutorial_coverage);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_coverage);
	    	String message = getString(R.string.tutorial_message_coverage);
	    	showTutorialDialog(key, title, message);
    	}
    }
    public void showTutorialConfigMap(){
    	String key = getString(R.string.pref_key_tutorial_config_map);
    	SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    	if(sharedPref.getBoolean(key, Parameters.App.show_tutorial)){
	    	String title = getString(R.string.tutorial_title_config_map);
	    	String message = getString(R.string.tutorial_message_config_map);
	    	showTutorialDialog(key, title, message);
    	}
    }
    private void showTutorialDialog(String key, String title, String message) {
    	DialogFragment newFragment = TutorialDialogFragment.newInstance(key, title, message);
    	newFragment.setCancelable(true);
    	newFragment.show(getFragmentManager(), "tutorial-"+title);
    }*/
    
    /**
     * Displays a confirmation dialog for reseting application configuration
     */
    /*private void resetUserConfigShowDialog() {
    	DialogFragment newFragment = ResetAppDialogFragment.newInstance();
    	newFragment.setCancelable(true);
    	newFragment.show(getFragmentManager(), "reset");
	}*/
    
    /**
     * Displays a confirmation dialog for reseting Missions database
     */
    /*private void resetMissionsDbShowDialog() {
    	DialogFragment newFragment = ResetDbDialogFragment.newInstance();
    	newFragment.setCancelable(true);
    	newFragment.show(getFragmentManager(), "reset_db");
	}*/
    
    Dialog rate_dialog;
    public void setRateDialog(Dialog dialog){
    	rate_dialog = dialog;
    }
    
    @Override
    protected void onPause() {//Pause simulator and browser
        super.onPause();
        if(rate_dialog!=null){
        	rate_dialog.dismiss();
        }
        /*if(simulator!=null){
        	simulator.pause();
        }*/
    }

    @Override
    protected void onResume() {//Resume browser
        super.onResume();
        this.simulator.reconstruct(this);
    }

    @Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
        if (mXwalkView != null) {
            mXwalkView.onActivityResult(requestCode, resultCode, data);
        }
        if (mXwalkViewOrbit != null) {
            mXwalkViewOrbit.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        if (mXwalkView != null) {
            mXwalkView.onNewIntent(intent);
        }
        if (mXwalkViewOrbit != null) {
            mXwalkViewOrbit.onNewIntent(intent);
        }
    	super.onNewIntent(intent);
    }
	
	@Override
    public void onDestroy() {//Disconnect simulator, close database and browser
        super.onDestroy();
        // store the data in the fragment
        if(isFinishing()){
        	simulator.disconnect();
            //((StavorApplication)getApplication()).db_help.close();
        }else{
        	dataFragment.setData(
        			this.simulator,
        			((StavorApplication)getApplication()).db_help,
        			((StavorApplication)getApplication()).db,
        			hud_panel_open
        			);
        	//Recycle background [NOT USED SINCE NEW ACTIVITY SPLASH SCREEN BUT SAVE FOR FUTURE IMPLEMENTATIONS]
            /*BitmapDrawable bd = (BitmapDrawable)getWindow().getDecorView().getBackground();
            Bitmap mBitmap = bd.getBitmap();
            if (mBitmap != null && !mBitmap.isRecycled()) {
            	getWindow().getDecorView().setBackgroundResource(0);
                bd.setCallback(null);
                mBitmap.recycle();
                mBitmap = null; 
            }*/
        }
      //Prevent onDestroy to avoid exception of illegalArgument: receiver not registered
    	try{
            mXwalkView.onDestroy();
    	}catch(Exception e){
    	}
    	try{
            mXwalkViewOrbit.onDestroy();
    	}catch(Exception e){
    	}
    }

	private boolean hud_panel_open;
	public boolean getHudPanelOpen(){
		return hud_panel_open;
	}
	public void setHudPanelOpen(boolean open){
		hud_panel_open = open;
	}
} public class StavorApplication extends MultiDexApplication {
	private String searchTerm = "";
	
	/**
	 * Used to store the last screen title. For use in restoreActionBar()
	 */
	public CharSequence mTitle;
	public int currentSection;
	
	//Global database objects (for multi-activity access)
	public ReaderDbHelper db_help;
    public SQLiteCursorLoader loader = null;
    public SQLiteDatabase db;
    
    public int modelViewId = R.id.menu_views_ref_frame_xyz;
    public int modelOrbitViewId = R.id.menu_orbviews_free;
    
    WebAppInterface jsInterface;

    public int follow_sc = R.id.menu_mapviews_free;
    public int zoom = 1;
    public float lon = (float) 0.0;
    public float lat = (float) 0.0;
	
	public void setSearchTerm(String searchTerm) {
		this.searchTerm = searchTerm;
	}
	
	public String getSearchTerm() {
		return this.searchTerm;
	}

} public class Parameters {
	/**
	 * General application parameters
	 * @author Xavier Gibert
	 *
	 */
	public static class App {
		
		public static final int splash_min_time_ms = 3000;//[ms] 3.0s min
		public static final boolean show_tests_section = false;
		public static final boolean pro_version = false;
		
		//FIRST RUN PARAMETERS
		public static final boolean show_guide = true;
		//Deprecated: it was the old crappy tutorial based on dialog boxes
		public static final boolean show_tutorial = false;
		public static final boolean show_orekit_data_installation_message = false;
		//If we want to show the sections menu open during the first run of the application and always until user makes use of it then set to false.
		public static final boolean first_start_app_closed_section_menu = true; 
	}
	/**
	 * About screen information
	 * @author Xavier Gibert
	 *
	 */
	public static class About {
		public static final String jocs_site = "http://jocsmobile.wordpress.com";
		public static final String orekit_site = "http://orekit.org";
		public static final String project_start_date = "2014/04/01";
		public static final String version_orekit = "7.X";
		public static final String version_xwalk = "13.42.319.11s";
		public static final String version_threejs = "r67";
		public static final String version_gson = "2.2.4";
		public static final String version_androidcolorpicker = "1.0";
		public static final String version_loader = "0.7.3";
		public static final String version_openlayers = "2.13.1";
		public static final String version_http = "1.2.1";
	}
	/**
	 * Visualization configuration
	 * @author Xavier Gibert
	 *
	 */
	public static class Hud {
		public static final boolean start_panel_open = true;
	}
	/**
	 * Simulator configuration
	 * @author Xavier Gibert
	 *
	 */
	public static class Simulator {
		public static final long min_hud_panel_refreshing_interval_ns = 500000000;//[ns] 2Hz max
		public static final long min_hud_model_refreshing_interval_ns = 40000000;//[ns] 25Hz max
		public static final long model_refreshing_interval_safe_guard_ns = 5000000;//[ns] 5ms
		public static final int amount_mission_examples = 7;
		public static class Remote{
			public static final int remote_connection_timeout_ms = 5000;//[ms]
			public static final String default_host = "192.168.1.2";
			public static final String default_port = "1520";
			public static boolean default_ssl = false;
			public static int objects_per_ssl_request = 50;
		}
	}
	/**
	 * URLs for the visualization and tests
	 * @author Xavier Gibert
	 *
	 */
	public static class Web {
		public static final String STARTING_PAGE = "file:///android_asset/www/huds/index.html";
		public static final String STARTING_PAGE_ORBIT = "file:///android_asset/www/huds/index_orbit.html";
		public static final String STARTING_PAGE_MAP = "file:///android_asset/www/map/index.html";
		//public static final String TEST_PAGE_1 = "file:///android_asset/www/index.html";
		//public static final String TEST_PAGE_1 = "http://127.0.0.1:8081/";
		//public static final String TEST_PAGE_1 = "http://webglreport.com";
		public static final String TEST_PAGE_1 = "http://get.webgl.org/";
		public static final String TEST_PAGE_2 = "http://doesmybrowsersupportwebgl.com/";
		public static final String TEST_PAGE_3 = "http://www.khronos.org/registry/webgl/sdk/tests/webgl-conformance-tests.html";
		public static final String LOCALHOST = "http://localhost:8080/";
	}
	public static class Map {
		//public static final double marker_pos_threshold = 0.2;//In deg
		public static final int station_visibility_points = 30;//Points in the polygon
		public static final int satellite_fov_points = 30;//30
		public static final double solar_terminator_points = 100;
		public static final double solar_terminator_threshold = 60*15;//In seconds
		public static final int satellite_track_max_points = 100;
	}
} public final class MissionReaderContract {
	public MissionReaderContract(){}
	
	/* Inner class that defines the table contents */
    public static abstract class MissionEntry implements BaseColumns {
        public static final String TABLE_NAME = "mission";
        public static final String COLUMN_NAME_NAME = "name";
        public static final String COLUMN_NAME_DESCRIPTION = "description";
        public static final String COLUMN_NAME_CLASS = "class";
    }

    private static final String TEXT_TYPE = " TEXT";
    private static final String SERIALIZED_TYPE = " BLOB";
    private static final String COMMA_SEP = ",";
    static final String SQL_CREATE_ENTRIES =
        "CREATE TABLE " + MissionEntry.TABLE_NAME + " (" +
        		MissionEntry._ID + " INTEGER PRIMARY KEY," +
        		MissionEntry.COLUMN_NAME_NAME + TEXT_TYPE + COMMA_SEP +
        		MissionEntry.COLUMN_NAME_DESCRIPTION + TEXT_TYPE + COMMA_SEP +
        		MissionEntry.COLUMN_NAME_CLASS + SERIALIZED_TYPE + 
        " )";

    static final String SQL_DELETE_ENTRIES =
        "DROP TABLE IF EXISTS " + MissionEntry.TABLE_NAME;

} public class ReaderDbHelper extends SQLiteOpenHelper {
	// If you change the database schema, you must increment the database version.
    public static final int DATABASE_VERSION = 3;
    public static final String DATABASE_NAME = "Missions.db";
    private MainActivity activity;
    
    public ReaderDbHelper(Context context, MainActivity activity) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.activity = activity;
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(MissionReaderContract.SQL_CREATE_ENTRIES);
        db.execSQL(StationsReaderContract.SQL_CREATE_ENTRIES);
        
        //Reset install database flag
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
        prefs.edit().putBoolean(activity.getString(R.string.pref_key_database_installed), false).commit();
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
    	
    	//Check if the user has introduced new entries
    		//Get all entries
    	
    	if(oldVersion==1){
	    	
			Cursor result =
				    db.rawQuery("select * from "+MissionReaderContract.MissionEntry.TABLE_NAME+" order by "+MissionReaderContract.MissionEntry._ID+" asc",null);
			
			activity.userMissions.clear();
			if(result.getCount()>3){
				for(int i = 3; i < result.getCount(); i++){
					result.moveToPosition(i);
					String name = result.getString(result.getColumnIndex(MissionReaderContract.MissionEntry.COLUMN_NAME_NAME));
					String description = result.getString(result.getColumnIndex(MissionReaderContract.MissionEntry.COLUMN_NAME_DESCRIPTION));
					byte[] serialclass = result.getBlob(result.getColumnIndex(MissionReaderContract.MissionEntry.COLUMN_NAME_CLASS));
					activity.userMissions.add(new UserMission(name, description, serialclass));
				}
			}
	    	
	        db.execSQL(MissionReaderContract.SQL_DELETE_ENTRIES);
    	}else if(oldVersion==2){
	    	
			Cursor result =
				    db.rawQuery("select * from "+MissionReaderContract.MissionEntry.TABLE_NAME+" order by "+MissionReaderContract.MissionEntry._ID+" asc",null);
			
			activity.userMissions.clear();
			if(result.getCount()>6){
				for(int i = 6; i < result.getCount(); i++){
					result.moveToPosition(i);
					String name = result.getString(result.getColumnIndex(MissionReaderContract.MissionEntry.COLUMN_NAME_NAME));
					String description = result.getString(result.getColumnIndex(MissionReaderContract.MissionEntry.COLUMN_NAME_DESCRIPTION));
					byte[] serialclass = result.getBlob(result.getColumnIndex(MissionReaderContract.MissionEntry.COLUMN_NAME_CLASS));
					activity.userMissions.add(new UserMission(name, description, serialclass));
				}
			}
	    	
	        db.execSQL(MissionReaderContract.SQL_DELETE_ENTRIES);
    	}
    	
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }

} public class SerializationUtil {
 
	/**
	 * Deserialize from byte array to Mission object
	 * @param serialized
	 * @return
	 */
    public static Mission deserialize(byte[] serialized) {
    	try {
    	     //byte b[] = serialized.getBytes(); 
    	     ByteArrayInputStream bi = new ByteArrayInputStream(serialized);
    	     ObjectInputStream si = new ObjectInputStream(bi);
    	     Mission obj = (Mission) si.readObject();
    	     si.close();
    	     return obj;
    	 } catch (Exception e) {
    	     System.out.println(e);
    	     return null;
    	 }
    }
 
    /**
     * Serialize the given object to byte array
     * @param obj
     * @return
     * @throws IOException
     */
    public static byte[] serialize(Object obj)//str.getBytes("UTF-8")
            throws IOException {
        ByteArrayOutputStream fos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(obj);
        oos.flush();
        //String tmp = fos.toString();
        byte[] ba = fos.toByteArray();
        fos.close();
        return ba;
    }
 
} public static abstract class MissionEntry implements BaseColumns {
    public static final String TABLE_NAME = "mission";
    public static final String COLUMN_NAME_NAME = "name";
    public static final String COLUMN_NAME_DESCRIPTION = "description";
    public static final String COLUMN_NAME_CLASS = "class";
} public class CopyMissionDialogFragment extends DialogFragment {
	private static final String ARG_NAME = "mission_name";
	private static final String ARG_ID = "mission_id";
	private static final String ARG_CLASS = "mission_class";
	
	public static CopyMissionDialogFragment newInstance(int id, String name, Mission mis_class) {	
		CopyMissionDialogFragment fragment = new CopyMissionDialogFragment();
		Bundle args = new Bundle();
		args.putString(ARG_NAME, name);
		args.putInt(ARG_ID, id);
		args.putSerializable(ARG_CLASS, mis_class);
		fragment.setArguments(args);
		return fragment;
	}
	int mission_id;
	Mission mission;
	
	@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
		String mis_name = getArguments().getString(ARG_NAME);
		int mis_id = getArguments().getInt(ARG_ID);
		mission_id = mis_id;
		mission = (Mission) getArguments().getSerializable(ARG_CLASS);
		
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(getString(R.string.dialog_copy_title))
        		.setMessage(getString(R.string.dialog_copy_message)+" "+mis_name+"?")
        		.setCancelable(true)
               .setPositiveButton(getString(R.string.dialog_copy_confirm), new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Dummy
                	   copyMission();
                   }

               });
               builder.setNegativeButton(getString(R.string.dialog_copy_cancel), new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancelled the dialog
                   }
               });
        // Create the AlertDialog object and return it
        return builder.create();
    }
	
	/**
	 * Delete Mission from database
	 * @param mission_id
	 */
	private void copyMission() {
		MainActivity act = ((MainActivity)getActivity());
		
		ContentValues values = new ContentValues();
		mission.name = mission.name+"_copy";
		values.put(MissionEntry.COLUMN_NAME_NAME, mission.name);
		values.put(MissionEntry.COLUMN_NAME_DESCRIPTION, mission.description);
		
		try {
			values.put(MissionEntry.COLUMN_NAME_CLASS, SerializationUtil.serialize(mission));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// Insert the new row
		((StavorApplication)act.getApplication()).loader.insert(
				MissionEntry.TABLE_NAME,
				null,
		         values);
		
	}

} public class DeleteMissionDialogFragment extends DialogFragment {
	private static final String ARG_NAME = "mission_name";
	private static final String ARG_ID = "mission_id";
	
	public static DeleteMissionDialogFragment newInstance(int id, String name) {	
		DeleteMissionDialogFragment fragment = new DeleteMissionDialogFragment();
		Bundle args = new Bundle();
		args.putString(ARG_NAME, name);
		args.putInt(ARG_ID, id);
		fragment.setArguments(args);
		return fragment;
	}
	int mission_id;
	
	@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
		String mis_name = getArguments().getString(ARG_NAME);
		int mis_id = getArguments().getInt(ARG_ID);
		mission_id = mis_id;
		
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(getString(R.string.dialog_delete_title))
        		.setMessage(getString(R.string.dialog_delete_message)+" "+mis_name)
        		.setCancelable(true)
               .setPositiveButton(getString(R.string.dialog_delete_confirm), new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Dummy
                	   deleteMission(mission_id);
                   }

               });
               builder.setNegativeButton(getString(R.string.dialog_delete_cancel), new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancelled the dialog
                   }
               });
        // Create the AlertDialog object and return it
        return builder.create();
    }
	
	/**
	 * Delete Mission from database
	 * @param mission_id
	 */
	private void deleteMission(int mission_id) {
		MainActivity act = ((MainActivity)getActivity());
		((StavorApplication)act.getApplication()).loader.delete(MissionEntry.TABLE_NAME, MissionEntry._ID+"="+mission_id, null);
	}

} public class Mission implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1987145766082906026L;
	
	public String name = "CustomMission";
	public String description = "Mission description";
	//public String initial_stage = "First Stage";
	public PropagatorType propagatorType = PropagatorType.Keplerian;
	public double sim_duration = 600000.;
	public double sim_step = 60.;
	public double initial_mass = 2000;
	public InertialFrames inertialFrame = InertialFrames.EME2000;
	//public RotatingFrames rotatingFrame = RotatingFrames.GTOD;
	public AbsoluteDate initial_date = new AbsoluteDate();
	public Orbit initial_orbit = new Orbit();
} public class MissionAndId implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 770862424275385258L;
	public Mission mission;
	public int id;
	
	public MissionAndId(Mission mis, int identif){
		mission=mis;
		id=identif;
	}
} public class Simulator {
	//General
	private SharedPreferences sharedPref;
	private Context context;
	private Activity activity;
	
	//Simulation core
	private SimulatorStatus simulatorStatus = SimulatorStatus.Disconnected;
	private SimulationStatus simulationStatus = SimulationStatus.Pause;
	private ThreadRemote thread_remote;
	private ThreadLocal thread_local;
	private Handler handler_remote, handler_local;
	
	//Results
	private ModelSimulation simulation;
	
	//GUI views
	private Button buttonConnect;
	private Switch switchSelector;
	
	//Mission
	private Mission mission;
	private int mission_id=-1;
	
	//Flags
	private boolean wasPlaying = false;//Flag to restore playing if fragment has paused-resumed while playing
	
	/**
	 * Pauses the simulator but keeping the previous status (playing/paused)
	 */
	public void temporaryPause(){
		if(simulatorStatus.equals(SimulatorStatus.Connected)){
			if(simulationStatus.equals(SimulationStatus.Play)){
				wasPlaying = true;
				pause();
			}else{
				wasPlaying = false;
			}
		}
	}
	/**
	 * restores the status of the simulator to the previous one before calling temporaryPause()
	 */
	public void resumeTemporaryPause(){
		if(wasPlaying){
			play();
		}
	}
	/**
	 * Resets the flag of the temporary pause, for when the simulator is reconnected.
	 */
	public void resetTemporaryPause(){
		wasPlaying = false;
	}
	
	/**
	 * Sets the mission before connecting the simulator
	 * @param mis
	 * @param id
	 */
	public void setSelectedMission(Mission mis, int id){
		mission = mis;
		mission_id = id;
	}

	/**
	 * Set no mission selected
	 */
	public void resetSelectedMissionId() {
		mission_id=-1;
	}
	
	/**
	 * Returns the selected mission id
	 * @return
	 */
	public int getSelectedMissionid(){
		return mission_id;
	}
	
	/**
	 * Set connect button View
	 * @param bt
	 */
	public void setButtonConnect(Button bt){
		buttonConnect=bt;
		updateConnectButtonText();
	}
	
	/**
	 * Set local/remote switch View
	 * @param st
	 */
	public void setSwitchView(Switch st){
		switchSelector=st;
		enableCorrectSimulatorViews();
	}
	
	/**
	 * Sets the Hud and browser view
	 * @param v
	 * @param x
	 */
	public void setHudView(Browsers type, View v, XWalkView x){
		simulation.setHud(type, v,x);
	}
	
	public void clearHud(){
		simulation.clearHud();
	}
	
	public void setBrowserLoaded(boolean is){
		simulation.setBrowserloaded(is);
	}
	

	private ProgressDialog progress;
	/**
	 * Sets the simulator connecting progress
	 * @param prog
	 */
	public void setProgress(final int prog){
		if(prog==10000 && progress==null){//Case of disconnecting simulator
		}else{
			if(progress==null){
				progress = new ProgressDialog(activity);
				progress.setProgressNumberFormat("");
				progress.setTitle(context.getString(R.string.dialog_simulator_title));
				progress.setMax(10000);
				progress.setMessage(context.getString(R.string.dialog_simulator_message));
				progress.setCancelable(false);
				progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				progress.setCanceledOnTouchOutside(false);
				progress.setIndeterminate(false);
				if(!activity.isFinishing())
					progress.show();
			} 
			progress.setProgress(prog);
			if(prog==10000){
				progress.dismiss();
				progress = null;
			}
			/*try{
				activity.runOnUiThread( new Runnable() {
					public void run() {
						activity.setProgress(prog);
			        }
				});
			}catch(NullPointerException nulle){
				
			}*/
		}
	}

	
	public Context getContext(){
		return context;
	}
	
	public Simulator(MainActivity act){
		reconstruct(act);
		context = activity.getApplicationContext();
		sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
		simulation = new ModelSimulation(act);
		handler_remote = new Handler();
		handler_local = new Handler();
	}
	public void reconstruct(MainActivity act){
		activity = act;
	}
	
	/**
	 * Returns the simulation step results
	 * @return
	 */
	public ModelSimulation getSimulationResults(){
		return simulation;
	}
	
	/**
	 * Returns the simulator status (Connected/Disconnected)
	 * @return
	 */
	public SimulatorStatus getSimulatorStatus(){
		return simulatorStatus;
	}
	
	/**
	 * Returns the simulation status (Play/Pause)
	 * @return
	 */
	public SimulationStatus getSimulationStatus(){
		return simulationStatus;
	}
	
	/**
	 * Connects the simulator
	 * @return
	 */
	public SimulatorStatus connect(){
		resetTemporaryPause();
		if(simulatorStatus.equals(SimulatorStatus.Disconnected)){
			simulationStatus = SimulationStatus.Pause;
			playCondition = new ConditionVariable(false);
			connectThread();
		}
		return simulatorStatus;
	}
	
	/**
	 * Disconnects the simulator
	 * @return
	 */
	public SimulatorStatus disconnect(){
		resetTemporaryPause();
		if(simulatorStatus.equals(SimulatorStatus.Connected)){
			resetSelectedMissionId();
			disconnectThread();

		}
		return simulatorStatus;
	}
	
	/**
	 * Play teh simulator
	 * @return
	 */
	public SimulationStatus play(){
		if(simulatorStatus.equals(SimulatorStatus.Connected)){
			if(simulationStatus.equals(SimulationStatus.Pause)){
				resumeThread();
				simulationStatus = SimulationStatus.Play;
				
				//********** Google Analytics ***********
				boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
				String remote_str = "Local";
				if(remote) remote_str = "Remote";
			}
		}
    	setCorrectSimulatorControls();
		return simulationStatus;
	}
	
	/**
	 * Pause the simulator
	 * @return
	 */
	public SimulationStatus pause(){
		if(simulatorStatus.equals(SimulatorStatus.Connected)){
			if(simulationStatus.equals(SimulationStatus.Play)){
				pauseThread();
				simulationStatus = SimulationStatus.Pause;
			}
		}
    	setCorrectSimulatorControls();
		return simulationStatus;
	}
	
	/**
	 * Stop the simulator
	 * @return
	 */
	public SimulationStatus stop(){
		if(simulatorStatus.equals(SimulatorStatus.Connected)){
			play();
			reset=true;
		}
		return simulationStatus;
	}
	protected boolean reset = false;
	protected ConditionVariable playCondition;//Play/Pause condition
	protected boolean cancel = false;
	
	/**
	 * Connects the thread corresponding to user selection (Local/Remote)
	 */
	private void connectThread() {
		setProgress(10 * 100);
		if(buttonConnect!=null){
			activity.runOnUiThread( new Runnable() {
				public void run() {
					buttonConnect.setEnabled(false);
		        }
			});
		}
		if(switchSelector!=null){
			activity.runOnUiThread( new Runnable() {
				public void run() {
					switchSelector.setEnabled(false);
		        }
			});
		}
		boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
		if(remote){
			// Remote
			try{
				setProgress(20 * 100);
				String host = sharedPref.getString(context.getString(R.string.pref_key_sim_remote_host), Parameters.Simulator.Remote.default_host);
				int port = Integer.parseInt(sharedPref.getString(context.getString(R.string.pref_key_sim_remote_port), Parameters.Simulator.Remote.default_port));
				setProgress(30 * 100);
				simulation = new ModelSimulation((MainActivity)activity);
				setProgress(40 * 100);
				simulation.preInitialize();
				setProgress(50 * 100);
				Boolean ssl = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_remote_ssl), Parameters.Simulator.Remote.default_ssl);
				thread_remote = new ThreadRemote(handler_remote,this,host,port,ssl);
				thread_remote.start();
			}catch(NumberFormatException nfe){
				setSimulatorStatus(SimulatorStatus.Disconnected);
			}
		}else{
			// Local
			setProgress(30 * 100);
			simulation = new ModelSimulation((MainActivity)activity);
			setProgress(40 * 100);
			simulation.preInitialize(); 
			setProgress(50 * 100);
			thread_local = new ThreadLocal(handler_local, ((MainActivity)activity).getSimulator(), mission);
			thread_local.start();
		}
	}
	
	/**
	 * Disconnects simulator thread
	 */
	private void disconnectThread() {
		boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
		if(remote){
			// Remote
			thread_remote.setDisconnected();
			
		}else{
			// Local
			cancel=true;
			playCondition.open();
		}
	}
	private void resumeThread() {
		boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
		if(remote){
		}else{
			playCondition.open();
		}
	}
	private void pauseThread() {
		boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
		if(remote){
		}else{
			playCondition.close();
		}
	}

	/**
	 * Sets the simulator status (Connected/Disconnected)
	 * @param new_status
	 */
	public void setSimulatorStatus(SimulatorStatus new_status) {
		simulatorStatus = new_status;
		updateConnectButtonText();
		enableCorrectSimulatorViews();
		setCorrectSimulatorControls();
		setProgress(100 * 100);
	}
	
	/**
	 * Sets the correct text in simulator button according to its status (Connected/Disconnected)
	 */
	public void updateConnectButtonText(){
		if(buttonConnect!=null){
			activity.runOnUiThread( new Runnable() {
				public void run() {
					buttonConnect.setEnabled(true);
					boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
					if(remote){
						if(simulatorStatus.equals(SimulatorStatus.Connected))
				    		buttonConnect.setText(context.getString(R.string.sim_disconnect));
				    	else
				    		buttonConnect.setText(context.getString(R.string.sim_connect));
					}else{
						if(simulatorStatus.equals(SimulatorStatus.Connected))
				    		buttonConnect.setText(context.getString(R.string.sim_stop));
				    	else
				    		buttonConnect.setText(context.getString(R.string.sim_start));
					}
		        }
			});
		}
	}
	
	/**
	 * Enable or disable the simulator mode switch and controls according to its status (Connected/Disconnected)
	 */
	private void enableCorrectSimulatorViews(){
			activity.runOnUiThread( new Runnable() {
				public void run() {
					if(switchSelector!=null){
						if(simulatorStatus.equals(SimulatorStatus.Connected))
				    		switchSelector.setEnabled(false);
				    	else
				    		switchSelector.setEnabled(true);
					}
		        }
			});
	}
	/*
	private static void enableView(ViewGroup layout, boolean enabled) {
	    layout.setEnabled(false);
	    for (int i = 0; i < layout.getChildCount(); i++) {
	        View child = layout.getChildAt(i);
	        if (child instanceof ViewGroup && !(child instanceof ListView) ) {
	            enableView((ViewGroup) child, enabled);
	        } else {
	            child.setEnabled(enabled);
	        }
	    }
	}*/

	private String message = "";
	public void showMessage(String string) {
		message = string;
		activity.runOnUiThread( new Runnable() {
			public void run() {
				Toast.makeText(context, message,
		                Toast.LENGTH_LONG).show();
	        }
		});
	}
	public void goToHud() {
		((MainActivity)activity).showSection(1);
	}
	
	ImageButton but_play;
	ImageButton but_stop;
	public void setControlButtons(ImageButton b_play, ImageButton b_stop) {
		but_play=b_play;
		but_stop=b_stop;
		
		//Listeners
		but_play.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
            	if(simulationStatus.equals(SimulationStatus.Play)){
            		pause();
            	}else{
            		play();
            	}
            }
        });
		but_stop.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
            	stop();
            }
        });

	}
	
	/**
	 * Change the play/pause icon according to simulation status
	 * and enable or disable the controls depending on simulator status
	 */
	public void setCorrectSimulatorControls() {
		if(but_play!=null && but_stop!=null){
			activity.runOnUiThread( new Runnable() {
				public void run() {
					boolean remote = sharedPref.getBoolean(context.getString(R.string.pref_key_sim_global_remote), false);
					if(remote){
						but_play.setVisibility(View.GONE);
						but_stop.setVisibility(View.GONE);
					}else{
						but_play.setVisibility(View.VISIBLE);
						but_stop.setVisibility(View.VISIBLE);
						if(getSimulatorStatus().equals(SimulatorStatus.Disconnected)){
							//but_play.setEnabled(false);
							//but_stop.setEnabled(false);
							but_play.setAlpha(0.4f);
							but_stop.setAlpha(0.4f);
							//Listeners
							but_play.setOnClickListener(new View.OnClickListener() {
					            public void onClick(View v) {
					                // Perform action on click
					            	Toast.makeText(activity.getApplicationContext(), activity.getString(R.string.sim_local_start_simulator_first), Toast.LENGTH_LONG).show();
					            }
					        });
							but_stop.setOnClickListener(new View.OnClickListener() {
					            public void onClick(View v) {
					                // Perform action on click
					            	Toast.makeText(activity.getApplicationContext(), activity.getString(R.string.sim_local_start_simulator_first), Toast.LENGTH_LONG).show();
					            }
					        });
						}else{
							//but_play.setEnabled(true);
							//but_stop.setEnabled(true);
							but_play.setAlpha(1.0f);
							but_stop.setAlpha(1.0f);
							if(getSimulationStatus().equals(SimulationStatus.Play)){
								//set pause drawable
								but_play.setImageDrawable(context.getResources().getDrawable(R.drawable.pause));
							}else{
								but_play.setImageDrawable(context.getResources().getDrawable(R.drawable.play));
							}
							//Listeners
							but_play.setOnClickListener(new View.OnClickListener() {
					            public void onClick(View v) {
					                // Perform action on click
					            	if(simulationStatus.equals(SimulationStatus.Play)){
					            		pause();
					            	}else{
					            		play();
					            	}
					            }
					        });
							but_stop.setOnClickListener(new View.OnClickListener() {
					            public void onClick(View v) {
					                // Perform action on click
					            	stop();
					            }
					        });
						}
					}
		        }
			});
		}
	}
	
} public enum SimulatorStatus {
	Connected, Disconnected;
}
import cs.si.stavor.R;
import cs.si.stavor.MainActivity;
import cs.si.stavor.StavorApplication;
import cs.si.stavor.app.Parameters;
import cs.si.stavor.database.MissionReaderContract;
import cs.si.stavor.database.ReaderDbHelper;
import cs.si.stavor.database.SerializationUtil;
import cs.si.stavor.database.MissionReaderContract.MissionEntry;
import cs.si.stavor.dialogs.CopyMissionDialogFragment;
import cs.si.stavor.dialogs.DeleteMissionDialogFragment;
import cs.si.stavor.mission.Mission;
import cs.si.stavor.mission.MissionAndId;
import cs.si.stavor.simulator.Simulator;
import cs.si.stavor.simulator.SimulatorStatus;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Fragment;
import android.content.Intent;
import android.content.Loader;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Switch;
import android.widget.Toast;
import android.widget.AbsListView.OnScrollListener;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import com.commonsware.cwac.loaderex.SQLiteCursorLoader;
            		//int tmp_sel = last_mission_selection;
            		simulator.disconnect();
            		//selectMissionInList(tmp_sel);
            		updateListSelection();
            	}else{
            		boolean remote = sharedPref.getBoolean(v.getContext().getString(R.string.pref_key_sim_global_remote), false);
            		if(remote){
	            		sharedPref.edit().putString(v.getContext().getString(
	            				R.string.pref_key_sim_remote_host),
	            				host_view.getText().toString()
	            				).commit();
	            		sharedPref.edit().putString(v.getContext().getString(
	            				R.string.pref_key_sim_remote_port), 
	            				port_view.getText().toString()
	            				).commit();
	            		sharedPref.edit().putBoolean(v.getContext().getString(
	            				R.string.pref_key_sim_remote_ssl), 
	            				checkSSL.isChecked()
	            				).commit();
	            		simulator.connect();
            		}else{
            			//Set mission
            			MissionAndId mis = getMission(activeMissionId);
            			if(mis!=null){
                			simulator.setSelectedMission(mis.mission, mis.id);
                			simulator.connect();
            			}else{
            				Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_local_cannot_deserialize_selected_mission), Toast.LENGTH_LONG).show();
            			}
            		}
            	}
            }
        });
    	
    	//Delete
    	Button button_delete = (Button)rootView.findViewById(R.id.buttonMissionDelete);
    	button_delete.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				//if(simulator.getSimulatorStatus().equals(SimulatorStatus.Connected)){
					//Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_stop_simulator_first), Toast.LENGTH_LONG).show();
				//}else{
					if(activeMissionId==-1){
						Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_local_select_first_a_mission), Toast.LENGTH_LONG).show();
					}else if (activeMissionId<=Parameters.Simulator.amount_mission_examples ){
						Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_local_mission_not_removable), Toast.LENGTH_LONG).show();
					}else{
						showDeleteMissionDialog(activeMissionId, activeMissionName);
					}
				//}
			}
    		
    	});
    	
    	//New
    	Button button_new = (Button)rootView.findViewById(R.id.buttonMissionNew);
    	button_new.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				//if(simulator.getSimulatorStatus().equals(SimulatorStatus.Connected)){
					//Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_stop_simulator_first), Toast.LENGTH_LONG).show();
				//}else{
					((MainActivity)getActivity()).showMissionCreator();
				//}
			}
    		
    	});
    	
    	//Edit
    	Button button_edit = (Button)rootView.findViewById(R.id.buttonMissionEdit);
    	button_edit.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				//if(simulator.getSimulatorStatus().equals(SimulatorStatus.Connected)){
					//Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_stop_simulator_first), Toast.LENGTH_LONG).show();
				//}else{
					if(activeMissionId==-1){
						Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_local_select_first_a_mission), Toast.LENGTH_LONG).show();
					}else if (activeMissionId<=Parameters.Simulator.amount_mission_examples){
						Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_local_mission_not_editable), Toast.LENGTH_LONG).show();
					}else{
						MissionAndId mis = getMission(activeMissionId);
		    			if(mis!=null){
		    				((MainActivity)getActivity()).showMissionEditor(mis);
		    			}else{
		    				Toast.makeText(getActivity().getApplicationContext(), getString(R.string.sim_local_cannot_deserialize_selected_mission), Toast.LENGTH_LONG).show();
		    			}
					}
				//}
			}
    		
    	});
    	
    	ImageView img_orekit = (ImageView)rootView.findViewById(R.id.nav_item_icon);
    	img_orekit.setOnClickListener(new View.OnClickListener(){
    	    public void onClick(View v){


    	        Intent intent = new Intent();
    	        intent.setAction(Intent.ACTION_VIEW);
    	        intent.addCategory(Intent.CATEGORY_BROWSABLE);
    	        intent.setData(Uri.parse(Parameters.About.orekit_site));
    	        startActivity(intent);
    	    }
    	});
    	
    	showGuideSimulator(rootView);
    	
		return rootView;
	}
	
	/**
	 * Returns the selected Mission from the database
	 * @return
	 */
	private MissionAndId getMission(int id){
		String[] projection = {
				MissionEntry._ID,
			    MissionEntry.COLUMN_NAME_CLASS
			    };
		Cursor c = ((StavorApplication)((MainActivity)getActivity()).getApplication()).db