/*
 * blanco Framework
 * Copyright (C) 2004-2006 IGA Tosiki
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.plugin.filemanager.views;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileType;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.program.Program;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

import blanco.plugin.filemanager.Activator;
import blanco.plugin.filemanager.BlancoFileManager;
import blanco.plugin.filemanager.preference.BlancoStringListFieldEditor;
import blanco.plugin.filemanager.vfs.BlancoVfsFileObjectEditorInput;

/**
 * ツリー選択がダブルクリックされたときの挙動を実装します。
 * 
 * @author IGA Tosiki
 */
public class BlancoFileManagerTreeSelectionDoubleClickAction extends Action {
    private TreeViewer fTreeViewer;

    public BlancoFileManagerTreeSelectionDoubleClickAction(
            final TreeViewer argViewer) {
        fTreeViewer = argViewer;
    }

    public void run() {
        final ITreeSelection treeSelection = (ITreeSelection) fTreeViewer
                .getSelection();
        processSelection(treeSelection);
    }

    public void processSelection(final ITreeSelection treeSelection) {
        try {
            final TreePath[] currentTreePaths = treeSelection.getPaths();
            final Object lastSegment = currentTreePaths[0].getLastSegment();

            if (lastSegment instanceof FileObject) {
                final FileObject fileObjectLook = (FileObject) lastSegment;
                if (fileObjectLook.getType() == FileType.FOLDER) {
                    // TODO ビュー連動は実装中です。
                    IViewPart part = PlatformUI
                            .getWorkbench()
                            .getActiveWorkbenchWindow()
                            .getActivePage()
                            .findView(
                                    "blanco.plugin.filemanager.views.BlancoFileManagerTableView");
                    if (part == null) {
                        // ビューが存在しない場合にのみ新規作成するようにしています。
                        // この条件判断が無いと操作感が低下してしまいます。
                        PlatformUI
                                .getWorkbench()
                                .getActiveWorkbenchWindow()
                                .getActivePage()
                                .showView(
                                        "blanco.plugin.filemanager.views.BlancoFileManagerTableView");
                    }

                    if (BlancoFileManager.getInstance().getTableView() != null) {
                        BlancoFileManager.getInstance().getTableView()
                                .setDirectory(fileObjectLook);
                    }

                } else if (fileObjectLook.getType() == FileType.FILE) {
                    final BlancoVfsFileObjectEditorInput input = new BlancoVfsFileObjectEditorInput(
                            fileObjectLook);
                    final IWorkbench workbench = PlatformUI.getWorkbench();
                    final IEditorDescriptor descriptor = workbench
                            .getEditorRegistry().getDefaultEditor(
                                    input.getName());
                    if (descriptor != null) {
                        IDE.openEditor(workbench.getActiveWorkbenchWindow()
                                .getActivePage(), input, descriptor.getId());
                    } else {
                        final IPath path = input.getPath();
                        if (path == null) {
                            // 処理続行できません。離脱します。
                            // file://以外の場合などにも、ここを通過します。
                            return;
                        }

                        final IPreferenceStore store = Activator.getDefault()
                                .getPreferenceStore();
                        final String[] patterns = BlancoStringListFieldEditor
                                .splitString(store
                                        .getString("file.execute.pattern"));

                        boolean isMatches = false;
                        for (int index = 0; index < patterns.length; index++) {
                            final Pattern patternCheck = Pattern
                                    .compile(patterns[index]);
                            final Matcher matcher = patternCheck.matcher(path
                                    .toFile().getName());
                            if (matcher.matches()) {
                                isMatches = true;
                                break;
                            }
                            System.out.println("ファイル["
                                    + path.toFile().getName() + "]はパターン["
                                    + patterns[index] + "]にマッチしません。");
                        }
                        if (isMatches == false) {
                            // このファイルは起動できません。
                            return;
                        }

                        // 外部プロセスの起動を実施します。
                        final boolean result[] = { false };
                        BusyIndicator.showWhile(PlatformUI.getWorkbench()
                                .getDisplay(), new Runnable() {
                            public void run() {
                                result[0] = Program.launch(path.toFile()
                                        .getAbsolutePath());
                            }
                        });
                    }
                }
            }
        } catch (PartInitException e) {
            MessageDialog.openInformation(fTreeViewer.getControl().getShell(),
                    "Directory View", "Exception:" + e.toString());
        } catch (FileSystemException e) {
            MessageDialog.openInformation(fTreeViewer.getControl().getShell(),
                    "Directory View", "Exception:" + e.toString());
        }
    }
}
