package jp.sourceforge.projects.ee2e.core.editors;
import jp.sourceforge.projects.ee2e.core.EE2EDebug;
import jp.sourceforge.projects.ee2e.core.EE2EPlugin;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.*;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.resources.IFile;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.part.*;

/**
 * To change this generated comment edit the template variable "typecomment":
 * Window&gt;Preferences&gt;Java&gt;Templates.
 * To enable and disable the creation of type comments go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation.
 *
 * @author Toshikazu Ando [ ando@park.ruru.ne.jp ]
 */
public class EE2EWindows extends Action {
    public EE2EWindows(int pos) {
        this.pos = pos;
        this.setText(
            EE2EPlugin.getResourceString("action.windows") + "(&" + pos + ")");
    }
    private static final String MARKER_ID = EE2EPlugin.PLUGIN_ID + ".windows";
    private static final String POS_NUMBER = "posNumber";
    private static final String NOW_NUMBER = "nowNumber";
    private static final String ACTIVE_FLAG = "activeFlag";
    private static final String BOOKMARK_ID =
        "org.eclipse.ui.views.BookmarkNavigator";

    /* (non-Javadoc)
     * @see org.eclipse.jface.action.IAction#run()
     */
    public void run() {
        IMarker[] allMarker = this.getPosMarker();
        int oldPos;
        if (allMarker.length <= 0) {
            oldPos = 1;
        } else {
            oldPos = allMarker[0].getAttribute(NOW_NUMBER, 0);
        }
        if (oldPos == this.pos) {
            return;
        }

        /* */
        EE2EPlugin plugin = EE2EPlugin.getDefault();
        if (plugin == null) {
            return;
        }
        IWorkbench bentch = plugin.getWorkbench();
        if (bentch == null) {
            return;
        }
        IWorkbenchPage activePage =
            bentch.getActiveWorkbenchWindow().getActivePage();
        if (activePage == null) {
            return;
        }
        IEditorPart activePart = activePage.getActiveEditor();
        for (int i = 0; i < allMarker.length; i++) {
            if (allMarker[i].getAttribute(POS_NUMBER, -1) != oldPos) {
                continue;
            }
            try {
                allMarker[i].delete();
            } catch (CoreException e) {
            }
        }
        allMarker = this.getPosMarker();
        IWorkbenchWindow window = bentch.getActiveWorkbenchWindow();
        EE2EDebug.printf(
            5,
            "IWorkbenchWindow=" + bentch.getWorkbenchWindows().length);
        if (window != null) {
            IWorkbenchPage page = window.getActivePage();
            EE2EDebug.printf(5, "IWorkbenchPage=" + window.getPages().length);
            if (page != null) {
                IEditorReference[] editorRefarence = page.getEditorReferences();
                for (int k = 0; k < editorRefarence.length; k++) {
                    IEditorPart part = editorRefarence[k].getEditor(false);
                    if (part == null) {
                        continue;
                    }
                    IEditorInput editorInput = part.getEditorInput();
                    if (editorInput == null) {
                        continue;
                    }
                    if (!(editorInput instanceof IFileEditorInput)) {
                        continue;
                    }
                    IResource resource =
                        ((IFileEditorInput) editorInput).getFile();
                    IMarker marker = null;
                    try {
                        String oldMakerId = MARKER_ID;
                        marker = resource.createMarker(oldMakerId);
                        marker.setAttribute(
                            IMarker.SEVERITY,
                            IMarker.SEVERITY_INFO);
                        boolean activeFlag = activePart.equals(part);
                        marker.setAttribute(
                            IMarker.MESSAGE,
                            this.getMessage(oldPos, activeFlag));
                        marker.setAttribute(IMarker.LOCATION, "No." + oldPos);
                        marker.setAttribute(
                            IMarker.PRIORITY,
                            IMarker.PRIORITY_LOW);
                        int lineNumber = this.getLineNumber(part);
                        marker.setAttribute(
                            IMarker.LINE_NUMBER,
                            lineNumber + 1);
                        marker.setAttribute(POS_NUMBER, oldPos);
                        marker.setAttribute(NOW_NUMBER, this.pos);
                        if (activeFlag) {
                            marker.setAttribute(ACTIVE_FLAG, true);
                        } else {
                            marker.setAttribute(ACTIVE_FLAG, false);
                        }
                    } catch (CoreException e) {
                        if (marker != null) {
                            try {
                                marker.delete();
                            } catch (CoreException e1) {
                            }
                        }
                    }
                    if (this.isMarkerExists(allMarker, pos, resource)) {
                        continue;
                    }
                    page.closeEditor(part, true);
                }
            }
        }
        activePart = null;
        for (int i = 0; i < allMarker.length; i++) {
            int localOldPos = allMarker[i].getAttribute(POS_NUMBER, -1);
            if (localOldPos != pos) {
                boolean activeFlag =
                    allMarker[i].getAttribute(ACTIVE_FLAG, false);
                try {
                    allMarker[i].setAttribute(NOW_NUMBER, this.pos);
                    allMarker[i].setAttribute(
                        IMarker.MESSAGE,
                        getMessage(localOldPos, activeFlag));
                } catch (CoreException e) {
                }
                continue;
            }
            IResource resource = allMarker[i].getResource();
            if (resource instanceof IFile) {
                try {
                    IEditorInput input = new FileEditorInput((IFile) resource);
                    IEditorPart part = activePage.openEditor(input,IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID);
                    int lineNumber =
                        allMarker[i].getAttribute(IMarker.LINE_NUMBER, 0) - 1;
                    this.setLineNumber(part, lineNumber);
                    if (allMarker[i].getAttribute(ACTIVE_FLAG, false)
                        == true) {
                        activePart = part;
                    }
                } catch (PartInitException e) {
                }
            }
            try {
                allMarker[i].delete();
            } catch (CoreException e1) {
            }
        }
        if (activePart != null) {
            activePage.activate(activePart);
        }
        this.openBookMark();
    }
    public String getMessage(int oldPos, boolean activeFlag) {
        String active;
        if (activeFlag) {
            active = "a";
        } else {
            active = "";
        }
        return "("
            + oldPos
            + "/"
            + this.pos
            + ")"
            + active
            + " EE2E "
            + EE2EPlugin.getResourceString("action.windows");
    }
    public int getLineNumber(IEditorPart editorPart) {
        if (!(editorPart instanceof AbstractTextEditor)) {
            return 0;
        }
        AbstractTextEditor editor = (AbstractTextEditor) editorPart;
        IDocumentProvider provider = editor.getDocumentProvider();
        IDocument document = provider.getDocument(editor.getEditorInput());
        ISelection selection = editor.getSelectionProvider().getSelection();
        if (!(selection instanceof ITextSelection)) {
            return 0;
        }
        int offset = ((ITextSelection) selection).getOffset();
        try {
            return document.getLineOfOffset(offset);
        } catch (BadLocationException e) {
        }
        return 0;
    }
    public void setLineNumber(IEditorPart editorPart, int lineNumber) {
        if (!(editorPart instanceof AbstractTextEditor)) {
            return;
        }
        AbstractTextEditor editor = (AbstractTextEditor) editorPart;
        IDocumentProvider provider = editor.getDocumentProvider();
        IDocument document = provider.getDocument(editor.getEditorInput());
        try {
            int start = document.getLineOffset(lineNumber);
            editor.selectAndReveal(start, 0);
        } catch (BadLocationException e) {
        }
    }

    protected boolean isMarkerExists(
        IMarker[] marker,
        int target,
        IResource resource) {
        for (int i = 0; i < marker.length; i++) {
            if ((marker[i].getAttribute(POS_NUMBER, -1) == target)
                && (marker[i].getResource().equals(resource))) {
                return true;
            }
        }
        return false;
    }
    protected IMarker[] getPosMarker() {
        IResource root = EE2EPlugin.getWorkspace().getRoot();
        IMarker[] marker;
        try {
            marker =
                root.findMarkers(MARKER_ID, true, IResource.DEPTH_INFINITE);
        } catch (CoreException e) {
            return null;
        }
        return marker;
    }
    protected void deleteMarkerExists(IMarker[] marker) {
        for (int i = 0; i < marker.length; i++) {
            try {
                marker[i].delete();
            } catch (CoreException e) {
            }
        }
    }
    protected void openBookMark() {
        EE2EPlugin plugin = EE2EPlugin.getDefault();
        if (plugin == null) {
            return;
        }
        IWorkbench bentch = plugin.getWorkbench();
        if (bentch == null) {
            return;
        }
        IWorkbenchWindow window = bentch.getActiveWorkbenchWindow();
        if (window == null) {
            return;
        }
        IWorkbenchPage page = window.getActivePage();
        if (page == null) {
            return;
        }
        try {
            page.showView(EE2EWindows.BOOKMARK_ID);
        } catch (PartInitException e) {
            EE2EDebug.printf(1,e.getMessage());
        }
    }
    private int pos;
}
