/*
 * FileTypeCommands.java
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.studio.client.common.filetypes;

import java.util.ArrayList;

import org.rstudio.core.client.Debug;
import org.rstudio.core.client.command.AppCommand;
import org.rstudio.core.client.command.CommandHandler;
import org.rstudio.studio.client.application.events.EventBus;
import org.rstudio.studio.client.common.filetypes.events.OpenSourceFileEvent;
import org.rstudio.studio.client.htmlpreview.model.HTMLPreviewServerOperations;
import org.rstudio.studio.client.server.ServerError;
import org.rstudio.studio.client.server.ServerRequestCallback;
import org.rstudio.studio.client.workbench.commands.Commands;
import org.rstudio.studio.client.workbench.model.HTMLCapabilities;
import org.rstudio.studio.client.workbench.views.packages.events.InstalledPackagesChangedEvent;
import org.rstudio.studio.client.workbench.views.packages.events.InstalledPackagesChangedHandler;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class FileTypeCommands
{
   public static class CommandWithId
   {
      private CommandWithId(String commandId, AppCommand command)
      {
         this.commandId = commandId;
         this.command = command;
      }

      public final String commandId;
      public final AppCommand command;
   }

   @Inject
   public FileTypeCommands(EventBus eventBus, 
                           Commands commands,
                           final HTMLPreviewServerOperations server)
   {
      eventBus_ = eventBus;
      commands_ = commands;

      rMDCommand_ = addRFileType(FileTypeRegistry.RMARKDOWN, "R _Markdown");
      addRFileType(FileTypeRegistry.RD, "R _Doc");
      
      addTextFileType(FileTypeRegistry.TEXT, "_Text File");
      addTextFileType(FileTypeRegistry.TEX, "Te_X File");
      addTextFileType(FileTypeRegistry.MARKDOWN, "Mar_kdown File");   
          
      eventBus.addHandler(InstalledPackagesChangedEvent.TYPE,
                          new InstalledPackagesChangedHandler() {
         @Override
         public void onInstalledPackagesChanged(InstalledPackagesChangedEvent e)
         {
            server.getHTMLCapabilities(
                  new ServerRequestCallback<HTMLCapabilities>() {

                     @Override
                     public void onResponseReceived(HTMLCapabilities caps)
                     {
                        setHTMLCapabilities(caps);
                     }
                     @Override
                     public void onError(ServerError error)
                     {
                        Debug.logError(error);
                     }
                  });
         }
      });
   }
  
   public ArrayList<CommandWithId> rFileCommandsWithIds()
   {
      return rFileTypeCommands_;
   }
   
   public ArrayList<CommandWithId> textFileCommandsWithIds()
   {
      return textFileTypeCommands_;
   }
   
   public TextFileType[] statusBarFileTypes()
   {
      ArrayList<TextFileType> types = new ArrayList<TextFileType>();
      types.add(FileTypeRegistry.R);
      types.add(FileTypeRegistry.SWEAVE);
      if (rMDCommand_.isEnabled())
         types.add(FileTypeRegistry.RMARKDOWN);
      types.add(FileTypeRegistry.TEXT);
      types.add(FileTypeRegistry.TEX);
      types.add(FileTypeRegistry.MARKDOWN);
      types.add(FileTypeRegistry.HTML);
      
      
      return (TextFileType[])types.toArray(new TextFileType[0]);
   }
   
   public HTMLCapabilities getHTMLCapabiliites()
   {
      return htmlCapabilities_;
   }
   
   public void setHTMLCapabilities(HTMLCapabilities caps)
   {
      htmlCapabilities_ = caps;
      rMDCommand_.setEnabled(caps.isRMarkdownSupported());
      rMDCommand_.setVisible(caps.isRMarkdownSupported());
   }
   
   private AppCommand addRFileType(TextFileType fileType, String menuLabel) 
   {
      return addType(rFileTypeCommands_, fileType, menuLabel);
   }
   
   private AppCommand addTextFileType(TextFileType fileType,  String menuLabel) 
   {
      return addType(textFileTypeCommands_, fileType, menuLabel);
   }

   
   private AppCommand addType(ArrayList<CommandWithId> typeList,
                              final TextFileType fileType, 
                              String menuLabel)
   {
      AppCommand command = new AppCommand();
      command.setMenuLabel(menuLabel);
      command.setImageResource(fileType.getDefaultIcon());
      command.addHandler(new CommandHandler()
      {
         public void onCommand(AppCommand command)
         {
            eventBus_.fireEvent(new OpenSourceFileEvent(null,
                                                        fileType));
         }
      });

      String commandId = commandIdForType(fileType);
      commands_.addCommand(commandId, command);
      typeList.add(new CommandWithId(commandId, command));
      return command;
   }
   
   private static String commandIdForType(FileType fileType)
   {
      return "filetype_" + fileType.getTypeId();
   }

   private final EventBus eventBus_;
   private final Commands commands_;
   
   private final ArrayList<CommandWithId> rFileTypeCommands_ =
         new ArrayList<CommandWithId>();
   
   private final ArrayList<CommandWithId> textFileTypeCommands_ =
         new ArrayList<CommandWithId>();
   
   private final AppCommand rMDCommand_;
   private HTMLCapabilities htmlCapabilities_;

}

@@ -1130,16 +1130,74 @@
 lities;%0A
+import org.rstudio.studio.client.workbench.model.Session;%0A
 import o
@@ -1280,24 +1280,24 @@
 angedEvent;%0A
-
 import org.r
@@ -1877,16 +1877,60 @@
 mmands,%0A
+                           Session session,%0A
         
@@ -2050,16 +2050,42 @@
 ommands;
+%0A      session_ = session;
 %0A%0A      
@@ -3992,32 +3992,155 @@
 biliites()%0A   %7B%0A
+      if (htmlCapabilities_ == null)%0A         setHTMLCapabilities(session_.getSessionInfo().getHTMLCapabilities());%0A      %0A
       return htm
@@ -5640,16 +5640,16 @@
 ntBus_;%0A
-
    priva
@@ -5677,16 +5677,51 @@
 mands_;%0A
+   private final Session session_;%0A
    %0A   p

correct sequence for initialization of html capabilities