/*
 * Created on 2004-08-12
 *
 * Part of the Symbian development plug-in for Eclipse
 * Copyright (C) Mikołaj Zalewski, 2004
 */
package pl.zalewski.mikolaj.symbdev;

import java.io.File;
import java.util.Properties;

import org.eclipse.core.runtime.Preferences;

/**
 * @author mikolaj
 *
 * A configuration entry for a Symbian SDK
 */
public class SymbianSDKEntry
{
  /**
   * Unknown Symbian version
   */
  public static final int SYMBIAN_UNKNOWN = 0;
  /**
   * Symbian OS 6.1 or earlier
   */
  public static final int SYMBIAN_6_1 = 61;
  /**
   * Symbian OS 7.0
   */
  public static final int SYMBIAN_7_0 = 70;
  /**
   * Symbian OS 7.0s
   */
  public static final int SYMBIAN_7_0S = 71;
  /**
   * Symbian OS 8.0 or later
   */
  public static final int SYMBIAN_8_0 = 80;
    
  /**
   * The SDK name
   */
  public String name;
	
  /**
   * The EPOC root variable to set. Note - it will contain the drive letter
   * which should not appear in the EPOCROOT variable. It allways end with '\\'
   */
  public String epocRoot="C:\\";

  /**
   * The tools root read from devices.xml.
   */
  public String toolsRoot=null;

  /**
   * The id of the default Win32 compiler to use or -1 if none.
   */
  public int win32ToolId=-1;
  
  /**
   * Returns the default Win32 compiler tool entry or null if none 
   * @return The entry given by win32ToolId or null if this data is -1 or invalid.
   */
  public Win32ToolEntry getWin32ToolEntry()
  {
  	if (win32ToolId==-1) return null;
  	return Win32ToolsList.getInstance().getEntry(win32ToolId);
  }

  /**
    * Updates the Win32ToolId both in the structure as well as in the
    * preference store  
    */
  public void setWin32ToolId(int id)
  {
	win32ToolId=id;
	SymbianSDKsList.getInstance().updateWin32ToolIdPref(name, id);
  }

  /**
   * Adds to the environment the EPOCROOT variable and the elements
   * of PATH
   * @param env the environment to alter
   */
  public void alterEnvironment(Properties env)
  {
    int index=epocRoot.indexOf(':');
    String epocRootEnv;
    if (index>0)
        epocRootEnv=epocRoot.substring(index+1);
    	else epocRootEnv=epocRoot;
  	env.setProperty("EPOCROOT", epocRootEnv);
    
    String epocRootPath;
    epocRootPath=epocRoot;
    
	String envPath=env.getProperty("PATH");
	if (envPath==null) envPath="";
	env.setProperty("PATH", toolsRoot+"epoc32\\tools;"+toolsRoot
	        +"epoc32\\gcc\\bin;"+envPath);  	
  }

  final static String DVERSION_PREFIX="dversion.sdkcache."; 
  final static String PROPERTY_PREFIX="sdkcache."; 
  final static String SYMBIAN_VERSION_POSTFIX=".symbianver";
  final static String SYMBIAN_HELP_POSTFIX=".sdkhelp";
  
  final static int DETECT_VERSION_NONE=0;
  final static int DETECT_VERSION_MINE=3;
  final static int DETECT_VERSION_USER=0x70000000;

  final protected boolean fileExists(String filename)
  {
    return new File(epocRoot+filename).exists();   
  }
  
  protected int detectSdkVersion()
  {
    int version=SYMBIAN_UNKNOWN;
    if (!fileExists("epoc32/include/e32base.h")) return version;        
    if (!fileExists("epoc32/include/e32std.h")) return version;    
    version=SYMBIAN_6_1;

    if (!fileExists("epoc32/include/mdaaudiooutputstream.h")) return version;
    if (!fileExists("epoc32/include/httperr.h")) return version;    
    version=SYMBIAN_7_0;
    
    if (!fileExists("epoc32/include/ImageConversion.h")) return version;
    if (!fileExists("epoc32/include/ecam.h")) return version;
    version=SYMBIAN_7_0S;

    if (!fileExists("epoc32/include/SpeechRecognitionUtility.h")) return version;
    version=SYMBIAN_8_0;
    
    return version;
  }
  
  /**
   * Sets the Symbian OS version. If it is set to SYMBIAN_UNKNOWN,
   * the plug-in will try to sutodetect it. If it is something other,
   * it will overwrite the result of the autodetection
   * @param version One of the SYMBIAN_* constants
   */
  public synchronized void setSymbianVersion(int version)
  {
      Preferences pluginPrefs=SymbdevPlugin.getDefault().getPluginPreferences();
      pluginPrefs.setValue(PROPERTY_PREFIX+name+SYMBIAN_VERSION_POSTFIX, version);
      if (version!=SYMBIAN_UNKNOWN)
          pluginPrefs.setValue(DVERSION_PREFIX+name+SYMBIAN_VERSION_POSTFIX, DETECT_VERSION_USER);
      	  else pluginPrefs.setValue(DVERSION_PREFIX+name+SYMBIAN_VERSION_POSTFIX, DETECT_VERSION_NONE);
      fSymbianVersion=version;
  }
  
  /**
   * Returns the version of Symbian OS detected by the plug-in ot
   * set up by the user 
   */
  public synchronized int getSymbianVersion()
  {
    if (fSymbianVersion==SYMBIAN_UNKNOWN)
    {
        Preferences pluginPrefs=SymbdevPlugin.getDefault().getPluginPreferences();
        int dversion=pluginPrefs.getInt(DVERSION_PREFIX+name+SYMBIAN_VERSION_POSTFIX);
        int cachedVersion=pluginPrefs.getInt(PROPERTY_PREFIX+name+SYMBIAN_VERSION_POSTFIX);
        
        if (dversion<DETECT_VERSION_MINE)
        {
            fSymbianVersion=detectSdkVersion();
            pluginPrefs.setValue(PROPERTY_PREFIX+name+SYMBIAN_VERSION_POSTFIX, fSymbianVersion);
            pluginPrefs.setValue(DVERSION_PREFIX+name+SYMBIAN_VERSION_POSTFIX, DETECT_VERSION_MINE);
        } else fSymbianVersion=cachedVersion;
    }
    return fSymbianVersion;
  }
  
  private String detectSdkHelp()
  {
      if (fileExists("Series60Doc/start.chm")) return "Series60Doc\\start.chm";
      if (fileExists("Series60Doc/s60_sdk_help.chm")) return "Series60Doc\\s60_sdk_help.chm";
      if (fileExists("Documentation/Index.html")) return "Documentation\\Index.html";
      if (fileExists("Series90Doc/")) return "Series90Doc\\";
      return null;
  }
  
  /**
   * @return The path to the SDK help of null if none detected. The path can
   * point to a *.chm, *.html file or a folder
   */
  public synchronized String getSDKHelp()
  {
      if (fSDKHelp==null)
      {
          Preferences pluginPrefs=SymbdevPlugin.getDefault().getPluginPreferences();
          int dversion=pluginPrefs.getInt(DVERSION_PREFIX+name+SYMBIAN_HELP_POSTFIX);
          String sdkHelp=pluginPrefs.getString(PROPERTY_PREFIX+name+SYMBIAN_HELP_POSTFIX);
          
          if (dversion<DETECT_VERSION_MINE)
          {
              sdkHelp=detectSdkHelp();
              if (sdkHelp!=null) fSDKHelp=epocRoot+sdkHelp;
                else fSDKHelp=null;
              pluginPrefs.setValue(PROPERTY_PREFIX+name+SYMBIAN_HELP_POSTFIX, (fSDKHelp!=null?fSDKHelp:""));
              pluginPrefs.setValue(DVERSION_PREFIX+name+SYMBIAN_HELP_POSTFIX, DETECT_VERSION_MINE);
          } else
          {
              if (sdkHelp.equals("")) fSDKHelp=null;
                else fSDKHelp=sdkHelp;
          }
      }
      return fSDKHelp;
  }
  
  public static String getSymbianVersionName(int v)
  {
      switch (v)
      {
        case SYMBIAN_UNKNOWN: return "unknown";
        case SYMBIAN_6_1:     return "6.1 or earlier";
        case SYMBIAN_7_0:     return "7.0";
        case SYMBIAN_7_0S:    return "7.0s";
        case SYMBIAN_8_0:     return "8.0";
        default:              return "(unknown)";
      }
  }
  
  public String getSymbianVersionName()
  {
      return getSymbianVersionName(getSymbianVersion());
  }
  
  private int fSymbianVersion = SYMBIAN_UNKNOWN;
  private String fSDKHelp = null;
}
