package com.quantum.editors;

import java.util.List;
import java.util.StringTokenizer;

import com.quantum.ImageStore;
import com.quantum.sql.parser.SQLParser;

import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;


/**
 * @author BC
 */
public class SQLContentOutlinePage extends ContentOutlinePage {
	
	class LabelProviderImpl implements ILabelProvider {
		public Image getImage(Object element) {
			return ImageStore.getImage(ImageStore.SCRIPT);
		}

		public String getText(Object element) {
			if (element != null && element instanceof String) {
				StringTokenizer tokenizer = new StringTokenizer((String) element);
				
				String token = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : "";
				
				if ("select".equalsIgnoreCase(token) 
						|| "update".equalsIgnoreCase(token)
						|| "insert".equalsIgnoreCase(token)
						|| "delete".equalsIgnoreCase(token)
						|| "grant".equalsIgnoreCase(token)) {
					return token;
				} else if (tokenizer.hasMoreTokens()) {
					return token + " " + tokenizer.nextToken();
				} else {
					return token;
				}
			} else {
				return element == null ? "" : element.toString();
			}
		}

		public void addListener(ILabelProviderListener listener) {
		}

		public void dispose() {
		}

		public boolean isLabelProperty(Object element, String property) {
			return false;
		}

		public void removeListener(ILabelProviderListener listener) {
		}
	}
	
	class ContentProviderImpl implements ITreeContentProvider {
		
		public Object[] getElements(Object inputElement) {
			if (inputElement != null && inputElement instanceof IDocument) {
				String text = ((IDocument) inputElement).get();
				List sql = SQLParser.parse(text);
				return sql.toArray();
			} else {
				return null;
			}
		}

		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

		public Object[] getChildren(Object parentElement) {
			return null;
		}

		public Object getParent(Object element) {
			return null;
		}

		public boolean hasChildren(Object element) {
			return false;
		}
	}
	
	private IDocumentListener listener;

	private final SQLDocumentProvider documentProvider;
	private IEditorInput editorInput;
	/**
	 * @param documentProvider
	 * @param editor
	 */
	public SQLContentOutlinePage(SQLDocumentProvider documentProvider, SQLEditor editor) {
		this.documentProvider = documentProvider;
	}
	
	

	public void createControl(Composite parent) {
		super.createControl(parent);
		
		final TreeViewer treeViewer = getTreeViewer();
		
		IDocument document = this.documentProvider.getDocument(this.editorInput);
		if (document != null) {
			treeViewer.setLabelProvider(new LabelProviderImpl());
			treeViewer.setContentProvider(new ContentProviderImpl());
			treeViewer.setInput(document);
			
			this.listener = new IDocumentListener() {

				public void documentAboutToBeChanged(DocumentEvent event) {
				}

				public void documentChanged(DocumentEvent event) {
					treeViewer.refresh();
				}
			};
			document.addDocumentListener(this.listener);
		}
	}
	/**
	 * @param editorInput
	 */
	public void setInput(IEditorInput editorInput) {
		this.editorInput = editorInput;
	}
	
	
	public void dispose() {
		if (this.listener != null) {
			IDocument document = this.documentProvider.getDocument(this.editorInput);
			if (document != null) {
				document.removeDocumentListener(this.listener);
				this.listener = null;
			}
		}
		super.dispose();
	}
}