/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.editors.text;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.content.IContentDescription;

import org.eclipse.core.resources.IFile;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.internal.editors.text.NLSUtility;

import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.ResourceAction;
import org.eclipse.ui.texteditor.RetargetTextEditorAction;
import org.eclipse.ui.texteditor.TextEditorAction;


/**
 * Action group for encoding actions.
 * @since 2.0
 * @deprecated As of 3.1, encoding needs to be changed via properties dialog
 */
@Deprecated
public class EncodingActionGroup extends ActionGroup {

	private static final String FILE_CONTENT_ENCODING_FORMAT= TextEditorMessages.ResourceInfo_fileContentEncodingFormat;
	private static final String FILE_CONTAINER_ENCODING_FORMAT= TextEditorMessages.ResourceInfo_fileContainerEncodingFormat;


	/**
	 * Action for setting the encoding of the editor to the value this action has
	 * been initialized with.
	 */
	static class PredefinedEncodingAction extends TextEditorAction {

		/** The target encoding of this action. */
		private String fEncoding;
		/** The action label. */
		private String fLabel;
		/** Indicates whether the target encoding is the default encoding. */
		private boolean fIsDefault;

		/**
		 * Creates a new action for the given specification.
		 *
		 * @param bundle the resource bundle
		 * @param prefix the prefix for lookups from the resource bundle
		 * @param encoding the target encoding
		 * @param editor the target editor
		 */
		public PredefinedEncodingAction(ResourceBundle bundle, String prefix, String encoding, ITextEditor editor) {
       		super(bundle, prefix, editor);
			fEncoding= encoding;
			if (prefix == null)
				setText(encoding);
			fLabel= getText();
		}

		/**
		 * Creates a new action for the given specification.
		 *
		 * @param bundle the resource bundle
		 * @param encoding the target encoding
		 * @param editor the target editor
		 */
		public PredefinedEncodingAction(ResourceBundle bundle, String encoding, ITextEditor editor) {
       		super(bundle, null, editor);
			fEncoding= encoding;
			setText(encoding);
			fLabel= getText();
		}

		/**
		 * Returns the encoding support of the action's editor.
		 *
		 * @return the encoding support of the action's editor or <code>null</code> if none
		 */
		private IEncodingSupport getEncodingSupport() {
			ITextEditor editor= getTextEditor();
			if (editor != null)
				return editor.getAdapter(IEncodingSupport.class);
			return null;
		}

		@Override
		public void run() {
			IEncodingSupport s= getEncodingSupport();
			if (s != null)
				s.setEncoding(fIsDefault ? null : fEncoding);
		}

		/**
		 * Returns the encoding currently used in the given editor.
		 *
		 * @param editor the editor
		 * @return the encoding currently used in the given editor or <code>null</code> if no encoding support is installed
		 */
		private String getEncoding(ITextEditor editor) {

			IEditorInput input= (editor.getEditorInput());
			if (input instanceof IFileEditorInput) {
				IFile file= ((IFileEditorInput)input).getFile();
				try {
					String explicitEncoding;
					explicitEncoding= file.getCharset(false);
					if (explicitEncoding == null)
						return null;
				} catch (CoreException e) {
					// continue - assume file is not using default encoding
				}
			}

			IEncodingSupport s= getEncodingSupport();
			if (s != null)
				return s.getEncoding();

			return null;
		}

		@Override
		public void update() {

			if (fEncoding == null) {
				setEnabled(false);
				return;
			}

			ITextEditor editor= getTextEditor();
			if (editor == null) {
				setEnabled(false);
				return;
			}

			// update label
			fIsDefault= IEncodingActionsConstants.DEFAULT.equals(fEncoding);
			if (fIsDefault)
				setText(getDefaultEncodingText(editor, fLabel));
			else
				setText(fLabel);

			// update enable state
			if (editor.isDirty())
				setEnabled(false);
			else
				setEnabled(true);

			// update checked state
			String current= getEncoding(editor);
			if (fIsDefault)
				setChecked(current == null);
			else
				setChecked(fEncoding.equals(current));
		}

	}

	/*
	 * @since 3.0
	 */
	private static String getDefaultEncodingText(ITextEditor editor, String defaultText) {
		IEditorInput input= (editor.getEditorInput());
		if (!(input instanceof IFileEditorInput))
			return defaultText;

		IFile file= ((IFileEditorInput)input).getFile();

		String format= FILE_CONTENT_ENCODING_FORMAT;
		String encoding;
		try {
			encoding= getEncodingFromContent(file);
			if (encoding == null) {
				format= FILE_CONTAINER_ENCODING_FORMAT;
				encoding= file.getParent().getDefaultCharset();
			}
		} catch (CoreException ex) {
			return defaultText;
		}

		return NLSUtility.format(format, encoding);
	}

	/*
	 * @since 3.0
	 */
	private static String getEncodingFromContent(IFile file) throws CoreException {
		IContentDescription description = file.getContentDescription();
		if (description != null) {
			byte[] bom= (byte[])description.getProperty(IContentDescription.BYTE_ORDER_MARK);
			if (bom == null)
				return (String)description.getProperty(IContentDescription.CHARSET);
			if (bom == IContentDescription.BOM_UTF_8)
				return TextEditorMessages.WorkbenchPreference_encoding_BOM_UTF_8;
			if (bom == IContentDescription.BOM_UTF_16BE)
				return TextEditorMessages.WorkbenchPreference_encoding_BOM_UTF_16BE;
			if (bom == IContentDescription.BOM_UTF_16LE)
				return TextEditorMessages.WorkbenchPreference_encoding_BOM_UTF_16LE;
		}

		return null;
	}

	/**
	 * Sets the encoding of an  editor to the value that has interactively been defined.
	 */
	static class CustomEncodingAction extends TextEditorAction {


		/*
		 * @see org.eclipse.ui.texteditor.TextEditorAction#TextEditorAction(ResourceBundle, String, ITextEditor)
		 */
		protected CustomEncodingAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
			super(bundle, prefix, editor);
		}

		@Override
		public void update() {
			ITextEditor editor= getTextEditor();
			setEnabled(editor != null && !editor.isDirty());
		}

		@Override
		public void run() {

			ITextEditor editor= getTextEditor();
			if (editor == null)
				return;

			IEncodingSupport encodingSupport= editor.getAdapter(IEncodingSupport.class);
			if (encodingSupport == null)
				return;

			String title= TextEditorMessages.Editor_ConvertEncoding_Custom_dialog_title;
			String message= TextEditorMessages.Editor_ConvertEncoding_Custom_dialog_message;
			IInputValidator inputValidator = new IInputValidator() {
				@Override
				public String isValid(String newText) {
					return (newText == null || newText.length() == 0) ? " " : null; //$NON-NLS-1$
				}
			};

			String initialValue= encodingSupport.getEncoding();
			if (initialValue == null)
				initialValue= encodingSupport.getDefaultEncoding();
			if (initialValue == null)
				initialValue= ""; //$NON-NLS-1$

			InputDialog d= new InputDialog(editor.getSite().getShell(), title, message, initialValue, inputValidator);
			if (d.open() == Window.OK)
				encodingSupport.setEncoding(d.getValue());
		}
	}


	/** List of predefined encodings. */
	private static final String[][] ENCODINGS;

	/** The default encoding. */
	private static final String SYSTEM_ENCODING;

	/**
	 * Initializer: computes the set of predefined encoding actions.
	 */
	static {

		String[][] encodings= {
			{ IEncodingActionsConstants.DEFAULT, IEncodingActionsHelpContextIds.DEFAULT, IEncodingActionsDefinitionIds.DEFAULT },
			{ IEncodingActionsConstants.US_ASCII, IEncodingActionsHelpContextIds.US_ASCII, IEncodingActionsDefinitionIds.US_ASCII },
			{ IEncodingActionsConstants.ISO_8859_1, IEncodingActionsHelpContextIds.ISO_8859_1, IEncodingActionsDefinitionIds.ISO_8859_1 },
			{ IEncodingActionsConstants.UTF_8, IEncodingActionsHelpContextIds.UTF_8, IEncodingActionsDefinitionIds.UTF_8 },
			{ IEncodingActionsConstants.UTF_16BE, IEncodingActionsHelpContextIds.UTF_16BE, IEncodingActionsDefinitionIds.UTF_16BE },
			{ IEncodingActionsConstants.UTF_16LE, IEncodingActionsHelpContextIds.UTF_16LE, IEncodingActionsDefinitionIds.UTF_16LE },
			{ IEncodingActionsConstants.UTF_16, IEncodingActionsHelpContextIds.UTF_16, IEncodingActionsDefinitionIds.UTF_16 }
		};

		String system= System.getProperty("file.encoding"); //$NON-NLS-1$
		if (system != null) {

			int i;
			for (i= 0; i < encodings.length; i++) {
				if (encodings[i][0].equals(system))
					break;
			}

			if (i != encodings.length) {
				// bring system encoding in second position - first is default encoding
				String[] s= encodings[i];
				encodings[i]= encodings[1];
				encodings[1]= s;
				// forget system encoding as it's already in the list
				system= null;
			}
		}

		SYSTEM_ENCODING= system;
		ENCODINGS= encodings;
	}



	/** List of encoding actions of this group. */
	private List<RetargetTextEditorAction> fRetargetActions= new ArrayList<>();

	/**
	 * Creates a new encoding action group for an action bar contributor.
	 */
	public EncodingActionGroup() {

		fRetargetActions.add(new RetargetTextEditorAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ConvertEncoding." + ENCODINGS[0][0] + ".", ENCODINGS[0][0], IAction.AS_RADIO_BUTTON)); //$NON-NLS-1$ //$NON-NLS-2$

		if (SYSTEM_ENCODING != null)
			fRetargetActions.add(new RetargetTextEditorAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ConvertEncoding.System.", IEncodingActionsConstants.SYSTEM, IAction.AS_RADIO_BUTTON)); //$NON-NLS-1$

		for (int i= 1; i < ENCODINGS.length; i++)
			fRetargetActions.add(new RetargetTextEditorAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ConvertEncoding." + ENCODINGS[i][0] + ".", ENCODINGS[i][0], IAction.AS_RADIO_BUTTON)); //$NON-NLS-1$ //$NON-NLS-2$

		fRetargetActions.add(new RetargetTextEditorAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ConvertEncoding.Custom.", IEncodingActionsConstants.CUSTOM, IAction.AS_PUSH_BUTTON)); //$NON-NLS-1$
	}

	@Override
	public void fillActionBars(IActionBars actionBars) {
		IMenuManager menuManager= actionBars.getMenuManager();
		IMenuManager editMenu= menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
		if (editMenu != null && fRetargetActions.size() > 0) {
			MenuManager subMenu= new MenuManager(TextEditorMessages.Editor_ConvertEncoding_submenu_label);
			subMenu.addMenuListener(new IMenuListener() {
				@Override
				public void menuAboutToShow(IMenuManager manager) {
					update();
				}
			});

			Iterator<RetargetTextEditorAction> e= fRetargetActions.iterator();
			subMenu.add(e.next());
			subMenu.add(new Separator());
			while (e.hasNext())
				subMenu.add(e.next());

			editMenu.add(subMenu);
		}
	}

	/**
	 * Retargets this action group to the given editor.
	 *
	 * @param editor the text editor to which the group should be retargeted
	 */
	public void retarget(ITextEditor editor) {
		fTextEditor= editor;
		Iterator<RetargetTextEditorAction> e= fRetargetActions.iterator();
		while (e.hasNext()) {
			RetargetTextEditorAction a= e.next();
			a.setAction(editor == null ? null : editor.getAction(a.getId()));
		}
	}


	//------------------------------------------------------------------------------------------


	/** Text editor this group is associated with. */
	private ITextEditor fTextEditor;

	/**
	 * Creates a new encoding action group for the given editor.
	 *
	 * @param editor the text editor
	 */
	public EncodingActionGroup(ITextEditor editor) {

		fTextEditor= editor;

		ResourceAction a;
		if (SYSTEM_ENCODING != null) {
			a= new PredefinedEncodingAction(TextEditorMessages.getBundleForConstructedKeys(), SYSTEM_ENCODING, editor);
			a.setHelpContextId(IEncodingActionsHelpContextIds.SYSTEM);
			a.setActionDefinitionId(IEncodingActionsDefinitionIds.SYSTEM);
			editor.setAction(IEncodingActionsConstants.SYSTEM, a);
		}

		for (int i= 0; i < ENCODINGS.length; i++) {
			a= new PredefinedEncodingAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ConvertEncoding." + ENCODINGS[i][0] + ".", ENCODINGS[i][0], editor); //$NON-NLS-1$ //$NON-NLS-2$
			a.setHelpContextId( ENCODINGS[i][1]);
			a.setActionDefinitionId( ENCODINGS[i][2]);
			editor.setAction(ENCODINGS[i][0], a);
		}

		a= new CustomEncodingAction(TextEditorMessages.getBundleForConstructedKeys(), "Editor.ConvertEncoding." + IEncodingActionsConstants.CUSTOM + ".", editor); //$NON-NLS-1$ //$NON-NLS-2$
		a.setHelpContextId(IEncodingActionsHelpContextIds.CUSTOM);
		a.setActionDefinitionId(IEncodingActionsDefinitionIds.CUSTOM);
		editor.setAction(IEncodingActionsConstants.CUSTOM, a);
	}

	/**
	 * Updates all actions of this action group.
	 */
	public void update() {
		if (fTextEditor == null)
			return;

		IAction a= fTextEditor.getAction(IEncodingActionsConstants.SYSTEM);
		if (a instanceof IUpdate)
			((IUpdate) a).update();

		for (int i= 0; i < ENCODINGS.length; i++) {
			a= fTextEditor.getAction(ENCODINGS[i][0]);
			if (a instanceof IUpdate)
				((IUpdate) a).update();
		}

		a= fTextEditor.getAction(IEncodingActionsConstants.CUSTOM);
		if (a instanceof IUpdate)
			((IUpdate) a).update();
	}

	@Override
	public void dispose() {
		if (fTextEditor != null) {
			fTextEditor.setAction(IEncodingActionsConstants.SYSTEM, null);
			for (int i= 0; i < ENCODINGS.length; i++)
				fTextEditor.setAction(ENCODINGS[i][0], null);
			fTextEditor.setAction(IEncodingActionsConstants.CUSTOM, null);

			fTextEditor= null;
		}
	}
}
