package com.ericsson.uecontrol.gui.fragments;


import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.ericsson.uecontrol.R;

import org.apache.log4j.Logger;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * Allow user to select destination directory and to enter filename.
 * */
public class FileBrowserDialog extends DialogFragment
		implements OnItemClickListener, DialogInterface.OnKeyListener, DialogInterface.OnClickListener, TextWatcher {
    public static final Logger log = Logger.getLogger(FileBrowserDialog.class);
    public static final int FOLDER_ICON = R.drawable.folder;
    public static final int FILE_ICON = R.drawable.file;

    public static interface OnFileSelectionListener{
        public void onFileSelection(String tag, File file);
    }
    public static enum BrowserMode{
        SELECT_FILE, NEW_FILE
    }

    private BrowserMode mode;
    private File root;
    private File path;
    private File selection;
    private TextView pathView;
    private ListView fileListView;
    private EditText fileNameView;
    private OnFileSelectionListener callback;


    public static FileBrowserDialog newInstance(String root, BrowserMode mode) {
        FileBrowserDialog browser = new FileBrowserDialog();
        Bundle bundle = new Bundle();
        bundle.putString("root", root);
        bundle.putString("browser_mode", mode.name());
        browser.setArguments(bundle);
        return browser;
    }


    @Override
	public void onAttach(Activity activity) {
        if(!(activity instanceof OnFileSelectionListener))
            throw new ClassCastException(activity.toString() + " must implement OnFileSelectionListener");

        Bundle bundle = this.getArguments();
        root = new File(bundle.getString("root"));
        callback = (OnFileSelectionListener) activity;
        mode = BrowserMode.valueOf(bundle.getString("browser_mode"));
		super.onAttach(activity);
	}

	/** Build the popup.  
	 * */
	@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Fix for CopyPaste bar not visible
        final Context context = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light);

        LinearLayout rootView = new LinearLayout(context);
        rootView.setOrientation(LinearLayout.VERTICAL);
        rootView.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT));
        int padding = getResources().getDimensionPixelSize(R.dimen.standard_padding);
        rootView.setPadding(padding, padding, padding, padding);


        pathView = new TextView(context);
        pathView.setText(root.getAbsolutePath());
        pathView.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        rootView.addView(pathView);

        fileListView = new ListView(context);
        fileListView.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, // Width
                LinearLayout.LayoutParams.MATCH_PARENT, // Height
                1f // Weight
        ));
        fileListView.setOnItemClickListener(this);
        fileListView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
        updateFileList(root);
        rootView.addView(fileListView);

        if(mode == BrowserMode.NEW_FILE){
            View delimiter = new View(context);
            delimiter.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            delimiter.getLayoutParams().height = 2;
            delimiter.setBackgroundResource(android.R.color.darker_gray);
            rootView.addView(delimiter);

            fileNameView = new EditText(context);
            fileNameView.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            fileNameView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
            fileNameView.setHint("File Name");
            fileNameView.addTextChangedListener(this);
            rootView.addView(fileNameView);
        }

        // Create dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("File Browser");
        builder.setOnKeyListener(this);
        builder.setPositiveButton(R.string.action_select, this);
        builder.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                FileBrowserDialog.this.getDialog().cancel();
            }
        });
        builder.setView(rootView);

        AlertDialog dialog = builder.create();
        dialog.show();
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
        return dialog;
    }

    /**
     * A file or folder has been clicked
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        File file = (File)fileListView.getAdapter().getItem(position);
        if(file.isDirectory()){
            updateFileList(file);
        }
        else if(mode == BrowserMode.SELECT_FILE){
            log.debug("File selected: "+ file.getAbsolutePath());
            ((AlertDialog)this.getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
            selection = file;
            ((FileListAdapter)fileListView.getAdapter()).notifyDataSetChanged();
        }
        else if(mode == BrowserMode.NEW_FILE){
            log.debug("File selected: "+ file.getAbsolutePath());
            fileNameView.setText(file.getName());
        }
    }

    /**
     * The "select" button has been pressed
     */
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if(mode == BrowserMode.SELECT_FILE && selection != null)
            callback.onFileSelection(FileBrowserDialog.this.getTag(), selection);
        else if(mode == BrowserMode.NEW_FILE && !fileNameView.getText().toString().isEmpty())
            callback.onFileSelection(FileBrowserDialog.this.getTag(),
                    new File(path, fileNameView.getText().toString()));
        else
            Toast.makeText(this.getActivity(), "No File Selected", Toast.LENGTH_SHORT).show();
    }

    /**
     * Back button has been pressed
     */
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
            if(root.equals(path))
                dialog.dismiss();
            else
                updateFileList(path.getParentFile());
            return true;
        }
        return false;
    }

    /**
     * Text input event for new file text field
     */
    @Override
    public void afterTextChanged(Editable editable) {
        if(this.getDialog() != null) {
            if (fileNameView.getText().toString().isEmpty())
                ((AlertDialog) this.getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
            else
                ((AlertDialog) this.getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
        }
    }
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}


    private void updateFileList(File dir){
        if(!dir.isDirectory())
            dir = dir.getParentFile();
        if(dir.compareTo(root) <= 0)
            dir = root;

        log.debug("Listing folder: "+ dir.getAbsolutePath());
        ArrayList<File> folders = new ArrayList();
        ArrayList<File> files = new ArrayList();
        for(File file : dir.listFiles()){
            if(file.isDirectory())
                folders.add(file);
            else
                files.add(file);
        }
        Collections.sort(folders);
        Collections.sort(files);
        folders.addAll(files);

        path = dir;
        pathView.setText(dir.getAbsolutePath());
        fileListView.setAdapter(new FileListAdapter(this.getActivity(), folders));

        // Reset selection
        selection = null;
        if(this.getDialog() != null &&
                (mode == BrowserMode.SELECT_FILE ||
                 mode == BrowserMode.NEW_FILE && fileNameView.getText().toString().isEmpty()))
            ((AlertDialog)this.getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    }

    protected class FileListAdapter extends ArrayAdapter<File>{
        private List<File> fileList;

        public FileListAdapter(Context context, List<File> fileList) {
            super(context, android.R.layout.simple_list_item_1, fileList);
            this.fileList = fileList;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textview = (TextView) super.getView( position, convertView, parent );
            textview.setPadding(5, 10, 10, 10);

            File file = fileList.get(position);
            textview.setText(file.getName());

            Drawable icon = getActivity().getResources().getDrawable(
                    ( file.isDirectory() ? FOLDER_ICON : FILE_ICON )
            );
            textview.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null );

            // Is selected?
            if (position == fileList.indexOf(selection))
                textview.setBackgroundResource(android.R.color.darker_gray);
            else
                textview.setBackgroundResource(android.R.color.transparent);

            return textview;
        }
    }
}
