/*
 * Copyright 2011 Jon S Akhtar (Sylvanaar)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.sylvanaar.idea.Lua.editor.completion;

import com.intellij.codeInsight.completion.CompletionLocation;
import com.intellij.codeInsight.completion.CompletionWeigher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.ResolveResult;
import com.sylvanaar.idea.Lua.lang.psi.LuaPsiFile;
import com.sylvanaar.idea.Lua.lang.psi.symbols.LuaCompoundIdentifier;
import com.sylvanaar.idea.Lua.lang.psi.symbols.LuaLocalIdentifier;
import com.sylvanaar.idea.Lua.lang.psi.symbols.LuaSymbol;
import org.jetbrains.annotations.NotNull;


/**
 * Created by IntelliJ IDEA.
 * User: Jon S Akhtar
 * Date: 9/3/11
 * Time: 7:41 AM
 */
public class LuaCompletionWeigher extends CompletionWeigher {
    private static final Logger log = Logger.getInstance("Lua.CompletionWeigher");
    @Override
    public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) {
        Object o = element.getObject();
        if (o instanceof ResolveResult) {
          o = ((ResolveResult)o).getElement();
        }

        if (o instanceof String) return SymbolWeight.anyGlobalFromCache;

        final PsiElement position = location.getCompletionParameters().getPosition();
        final String text = position.getText();
        final PsiFile containingFile = position.getContainingFile();
        if (!(containingFile instanceof LuaPsiFile )) {
          return null;
        }

        log.debug("weigh " + o + " " + position);

        if (! (o instanceof LuaSymbol)) return null;

        if (position instanceof LuaCompoundIdentifier || StringUtil.containsAnyChar(".:[]", text)) {

        } else {
            if (o instanceof LuaCompoundIdentifier) {

            }
            if (o instanceof LuaLocalIdentifier) return SymbolWeight.aLocal;

            if (!((LuaSymbol) o).isValid()) return null;
            final PsiFile completionFile = ((LuaSymbol) o).getContainingFile();
            if (containingFile.equals(completionFile)) return SymbolWeight.aGlobalInFile;

            final VirtualFile completionFileVirtualFile = completionFile.getVirtualFile();
            final VirtualFile containingFileVirutalFile = location.getCompletionParameters().getOriginalFile().getVirtualFile();

            if (completionFileVirtualFile == null) return null;
            if (containingFileVirutalFile == null) return null;

            ProjectFileIndex index = ProjectRootManager.getInstance(location.getProject()).getFileIndex();

            if (index.isInContent(completionFileVirtualFile))
                return SymbolWeight.aProjectGlobal;

            

            if ((index.isInLibraryClasses(completionFileVirtualFile)))
                return SymbolWeight.aLibraryGlobal;
        }


        return null;
    }

  static enum SymbolWeight {
    anOnlyReadGlobal, anyGlobalFromCache, aLibraryGlobal, anSDKGlobal, aProjectGlobal, aGlobalInFile, aLocal
  }

  static enum CompoundSymbolWeight {
      anOnlyReadGlobal, anSDKGlobal, aLibraryGlobal, aProjectGlobal, aGlobalInFile
  }
}

@@ -1275,32 +1275,105 @@
 si.LuaPsiFile;%0D%0A
+import com.sylvanaar.idea.Lua.lang.psi.expressions.LuaModuleExpression;%0D%0A
 import com.sylva
@@ -2099,32 +2099,378 @@
 ;%0D%0A        %7D%0D%0A%0D%0A
+        if (element instanceof LuaLookupElement) %7B%0D%0A            boolean isFromTypeInference = false;%0D%0A            isFromTypeInference = ((LuaLookupElement) element).isTypeInfered();%0D%0A            log.debug(%22weigh %22 + o + %22 typed=%22 + isFromTypeInference);%0D%0A            if (isFromTypeInference) return SymbolWeight.aTypeInferedSymbol;%0D%0A        %7D%0D%0A%0D%0A
         if (o in
@@ -2930,32 +2930,130 @@
 return null;%0D%0A%0D%0A
+        if (position instanceof LuaModuleExpression)%0D%0A            return SymbolWeight.aModule;%0D%0A%0D%0A
         if (posi
@@ -4130,24 +4130,8 @@
 %0D%0A%0D%0A
-            %0D%0A%0D%0A
     
@@ -4277,28 +4277,25 @@
      return 
-null
+0
 ;%0D%0A    %7D%0D%0A%0D%0A
@@ -4288,32 +4288,40 @@
  0;%0D%0A    %7D%0D%0A%0D%0A  
+private 
 static enum Symb
@@ -4410,32 +4410,41 @@
  aProjectGlobal,
+ aModule,
  aGlobalInFile, 
@@ -4449,16 +4449,43 @@
 , aLocal
+,%0D%0A      aTypeInferedSymbol
 %0D%0A  %7D%0D%0A%0D
@@ -4487,16 +4487,24 @@
  %7D%0D%0A%0D%0A  
+private 
 static e
@@ -4548,36 +4548,39 @@
 nlyReadGlobal, a
-nSDK
+Library
 Global, aLibrary
@@ -4564,39 +4564,36 @@
 LibraryGlobal, a
-Library
+nSDK
 Global, aProject

change completion weights