/*
 * Copyright (c) 2012-2016 Arne Schwabe
 * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
 */

package de.blinkt.openvpn.activities;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.Manifest;
import android.annotation.TargetApi;

/*
 * This section is a derivative work from the original project.
 *
 * -----  Beginning of Section  -----
 *
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 *
 * You may use, distribute and modify this code under the
 * terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.

 * Contributor:  A. M. Jehad Sarkar  <amjehad.sarkar@route1.com>
 */
//import android.app.ActionBar;
//import android.app.ActionBar.Tab;
import android.support.v7.app.ActionBar; //android.app.ActionBar;
import android.support.v7.app.ActionBar.Tab; //android.app.ActionBar.Tab;
/*
 * -----  End of Section  -----
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 */

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;

/*
 * This section is a derivative work from the original project.
 *
 * -----  Beginning of Section  -----
 *
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 *
 * You may use, distribute and modify this code under the
 * terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.

 * Contributor:  A. M. Jehad Sarkar  <amjehad.sarkar@route1.com>
 */
//import android.app.Fragment;
//import android.app.FragmentTransaction;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
/*
 * -----  End of Section  -----
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 */

import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.widget.Toast;

import de.blinkt.openvpn.R;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.fragments.FileSelectionFragment;
import de.blinkt.openvpn.fragments.InlineFileTab;

public class FileSelect extends BaseActivity {
	public static final String RESULT_DATA = "RESULT_PATH";
	public static final String START_DATA = "START_DATA";
	public static final String WINDOW_TITLE = "WINDOW_TILE";
	public static final String NO_INLINE_SELECTION = "de.blinkt.openvpn.NO_INLINE_SELECTION";
	public static final String SHOW_CLEAR_BUTTON = "de.blinkt.openvpn.SHOW_CLEAR_BUTTON";
	public static final String DO_BASE64_ENCODE = "de.blinkt.openvpn.BASE64ENCODE";
    private static final int PERMISSION_REQUEST = 23621;

    private FileSelectionFragment mFSFragment;
	private InlineFileTab mInlineFragment;
	private String mData;
	private Tab inlineFileTab;
	private Tab fileExplorerTab;
	private boolean mNoInline;
	private boolean mShowClear;
	private boolean mBase64Encode;
	
		
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState); 
		setContentView(R.layout.file_dialog);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            checkPermission();

        mData = getIntent().getStringExtra(START_DATA);
		if(mData==null)
			mData=Environment.getExternalStorageDirectory().getPath();
		
		String title = getIntent().getStringExtra(WINDOW_TITLE);
		int titleId = getIntent().getIntExtra(WINDOW_TITLE, 0); //AK@Route1: ClassCastException: String cannot be cast to Integer; But it seems to be intended by (bad) designed. I does not crash on the exception.
		if(titleId!=0) 
			title =getString(titleId);
		if(title!=null)
			setTitle(title);
		
		mNoInline = getIntent().getBooleanExtra(NO_INLINE_SELECTION, false);
		mShowClear = getIntent().getBooleanExtra(SHOW_CLEAR_BUTTON, false);
		mBase64Encode = getIntent().getBooleanExtra(DO_BASE64_ENCODE, false);

/*
 * This section is a derivative work from the original project.
 *
 * -----  Beginning of Section  -----
 *
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 *
 * You may use, distribute and modify this code under the
 * terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.

 * Contributor:  A. M. Jehad Sarkar  <amjehad.sarkar@route1.com>
 */
		//ActionBar bar = getActionBar();
		ActionBar bar = getSupportActionBar(); // = getActionBar();
/*
 * -----  End of Section  -----
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 */

		bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); //AK@Route1: bar.setNavigationMode() DOES produce NullPointerException, if BaseActivity extends AppCompatActivity (not Activity) and we keep using android.app.ActionBar; I would use android.support.v7.app.ActionBar, but then MyTabsListener does not compile, unless I switch to use of android.support.v4.app.Fragment and android.support.v4.app.FragmentTransaction.
		fileExplorerTab = bar.newTab().setText(R.string.file_explorer_tab);
		inlineFileTab = bar.newTab().setText(R.string.inline_file_tab); 

		mFSFragment = new FileSelectionFragment();
		fileExplorerTab.setTabListener(new MyTabsListener<FileSelectionFragment>(this, mFSFragment));
		bar.addTab(fileExplorerTab);
		
		if(!mNoInline) {
			mInlineFragment = new InlineFileTab();
			inlineFileTab.setTabListener(new MyTabsListener<InlineFileTab>(this, mInlineFragment));
			bar.addTab(inlineFileTab);
		} else {
			mFSFragment.setNoInLine();
		}

		
	}


	@TargetApi(Build.VERSION_CODES.M)
	private void checkPermission() {
		if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST);
		}
	}

	@Override
	public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
		super.onRequestPermissionsResult(requestCode, permissions, grantResults);

		if (grantResults[0]  == PackageManager.PERMISSION_DENIED) {
			setResult(RESULT_CANCELED);
			finish();
		}
	}

	public boolean showClear() {
		if(mData == null || mData.equals(""))
			return false;
		else
			return mShowClear;
	}

	protected class MyTabsListener<T extends Fragment> implements ActionBar.TabListener //AK@Route1: if android.support.v7.app.ActionBar then (unless using android.support.v4.app.FragmentTransaction): error: FileSelect.MyTabsListener is not abstract and does not override abstract method onTabReselected(Tab,FragmentTransaction) in TabListener
	{
		private Fragment mFragment;
		private boolean mAdded=false;

		public MyTabsListener( Activity activity, Fragment fragment){
			this.mFragment = fragment;
		}

		@Override //AK@Route1: if android.support.v7.app.ActionBar then (unless using android.support.v4.app.FragmentTransaction): error: method does not override or implement a method from a supertype
		public void onTabSelected(Tab tab, FragmentTransaction ft) {
			// Check if the fragment is already initialized
			if (!mAdded) {
				// If not, instantiate and add it to the activity
				ft.add(android.R.id.content, mFragment);
				mAdded =true;
			} else {
				// If it exists, simply attach it in order to show it
				ft.attach(mFragment);
			}
		}	        

		@Override //AK@Route1: if android.support.v7.app.ActionBar then (unless using android.support.v4.app.FragmentTransaction): error: method does not override or implement a method from a supertype
		public void onTabUnselected(Tab tab, FragmentTransaction ft) {
			ft.detach(mFragment);
		}

		@Override //AK@Route1: if android.support.v7.app.ActionBar then (unless using android.support.v4.app.FragmentTransaction): error: method does not override or implement a method from a supertype
		public void onTabReselected(Tab tab, FragmentTransaction ft) {

		}
	}
	
	public void importFile(String path) {
		File ifile = new File(path);
		Exception fe = null;
		try {

			String data = "";
			
			byte[] fileData = readBytesFromFile(ifile) ;
			if(mBase64Encode)
				data += Base64.encodeToString(fileData, Base64.DEFAULT);
			else
				data += new String(fileData);
			
			mData =data;
			
			/*
			mInlineFragment.setData(data);
			getActionBar().selectTab(inlineFileTab); */
			saveInlineData(ifile.getName(), data);
		} catch (IOException e) {
			fe =e;
		}
		if(fe!=null) {
			Builder ab = new AlertDialog.Builder(this);
			ab.setTitle(R.string.error_importing_file);
			ab.setMessage(getString(R.string.import_error_message) + "\n" + fe.getLocalizedMessage());
			ab.setPositiveButton(android.R.string.ok, null);
			ab.show();
		}
	}

	static private byte[] readBytesFromFile(File file) throws IOException {
		InputStream input = new FileInputStream(file);

		long len= file.length();
        if (len > VpnProfile.MAX_EMBED_FILE_SIZE)
            throw new IOException("selected file size too big to embed into profile");

		// Create the byte array to hold the data
		byte[] bytes = new byte[(int) len];

		// Read in the bytes
		int offset = 0;
		int bytesRead = 0;
		while (offset < bytes.length
				&& (bytesRead=input.read(bytes, offset, bytes.length-offset)) >= 0) {
			offset += bytesRead;
		}

		input.close();
		return bytes;
	}
	
	
	public void setFile(String path) {
		Intent intent = new Intent();
		intent.putExtra(RESULT_DATA, path);
		setResult(Activity.RESULT_OK,intent);
		finish();		
	}

	public String getSelectPath() {
		if(VpnProfile.isEmbedded(mData))
			return mData;
		else
			return Environment.getExternalStorageDirectory().getPath();
	}

	public CharSequence getInlineData() {
		if(VpnProfile.isEmbedded(mData))
			return VpnProfile.getEmbeddedContent(mData);
		else
			return "";
	}
	
	public void clearData() {
		Intent intent = new Intent();
		intent.putExtra(RESULT_DATA, (String)null);
		setResult(Activity.RESULT_OK,intent);
		finish();
		
	}

	public void saveInlineData(String fileName, String string) {
		Intent intent = new Intent();
        if(fileName==null)
            intent.putExtra(RESULT_DATA, VpnProfile.INLINE_TAG + string);
        else
		    intent.putExtra(RESULT_DATA,VpnProfile.DISPLAYNAME_TAG + fileName + VpnProfile.INLINE_TAG + string);
		setResult(Activity.RESULT_OK, intent);
		finish();
	}
}
