package com.intellij.lang.javascript.flex;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.flex.model.bc.BuildConfigurationNature;
import com.intellij.flex.model.bc.OutputType;
import com.intellij.flex.model.bc.TargetPlatform;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.lang.javascript.flex.projectStructure.FlexBuildConfigurationsExtension;
import com.intellij.lang.javascript.flex.projectStructure.model.FlexBuildConfiguration;
import com.intellij.lang.javascript.flex.projectStructure.model.ModifiableFlexBuildConfiguration;
import com.intellij.lang.javascript.flex.projectStructure.model.impl.Factory;
import com.intellij.lang.javascript.flex.projectStructure.model.impl.FlexProjectConfigurationEditor;
import com.intellij.lang.javascript.flex.projectStructure.ui.CreateHtmlWrapperTemplateDialog;
import com.intellij.lang.javascript.flex.run.FlashRunConfiguration;
import com.intellij.lang.javascript.flex.run.FlashRunConfigurationType;
import com.intellij.lang.javascript.flex.run.FlashRunnerParameters;
import com.intellij.lang.javascript.flex.sdk.FlexSdkUtils;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.WebModuleBuilder;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
public class FlexModuleBuilder extends ModuleBuilder {
private TargetPlatform myTargetPlatform = TargetPlatform.Web;
private boolean isPureActionScript = false;
private OutputType myOutputType = OutputType.Application;
private boolean myAndroidEnabled;
private boolean myIOSEnabled;
private Sdk myFlexSdk;
private String myTargetPlayer;
private boolean myCreateSampleApp;
private String mySampleAppName;
private boolean myCreateHtmlWrapperTemplate;
private boolean myEnableHistory;
private boolean myCheckPlayerVersion;
private boolean myExpressInstall;
public ModuleType getModuleType() {
return FlexModuleType.getInstance();
}
public void setTargetPlatform(final TargetPlatform targetPlatform) {
myTargetPlatform = targetPlatform;
}
public void setPureActionScript(final boolean pureActionScript) {
isPureActionScript = pureActionScript;
}
public void setOutputType(final OutputType outputType) {
myOutputType = outputType;
}
public void setAndroidEnabled(final boolean enabled) {
myAndroidEnabled = enabled;
}
public void setIOSEnabled(final boolean enabled) {
myIOSEnabled = enabled;
}
public void setFlexSdk(final Sdk flexSdk) {
myFlexSdk = flexSdk;
}
public void setTargetPlayer(final String targetPlayer) {
myTargetPlayer = targetPlayer;
}
public void setCreateSampleApp(final boolean createSampleApp) {
myCreateSampleApp = createSampleApp;
}
public void setSampleAppName(final String sampleAppName) {
mySampleAppName = sampleAppName;
}
public void setCreateHtmlWrapperTemplate(final boolean createHtmlWrapperTemplate) {
myCreateHtmlWrapperTemplate = createHtmlWrapperTemplate;
}
public void setHtmlWrapperTemplateParameters(final boolean enableHistory,
final boolean checkPlayerVersion,
final boolean expressInstall) {
myEnableHistory = enableHistory;
myCheckPlayerVersion = checkPlayerVersion;
myExpressInstall = expressInstall;
}
public void setupRootModel(final ModifiableRootModel modifiableRootModel) throws ConfigurationException {
final ContentEntry contentEntry = doAddContentEntry(modifiableRootModel);
if (contentEntry == null) return;
final VirtualFile sourceRoot = createSourceRoot(contentEntry);
final Module module = modifiableRootModel.getModule();
final FlexProjectConfigurationEditor currentFlexEditor =
FlexBuildConfigurationsExtension.getInstance().getConfigurator().getConfigEditor();
final boolean needToCommitFlexEditor = currentFlexEditor == null;
final FlexProjectConfigurationEditor flexConfigEditor;
flexConfigEditor = currentFlexEditor != null
? currentFlexEditor
: FlexProjectConfigurationEditor
.createEditor(module.getProject(), Collections.singletonMap(module, modifiableRootModel), null, null);
final ModifiableFlexBuildConfiguration[] configurations = flexConfigEditor.getConfigurations(module);
assert configurations.length == 1;
final ModifiableFlexBuildConfiguration bc = configurations[0];
setupBC(modifiableRootModel, bc);
if (bc.getOutputType() == OutputType.Application) {
createRunConfiguration(module, bc);
}
if (sourceRoot != null && myCreateSampleApp && myFlexSdk != null) {
try {
final boolean flex4 = !FlexSdkUtils.isAirSdkWithoutFlex(myFlexSdk) &&
StringUtil.compareVersionNumbers(myFlexSdk.getVersionString(), "4") >= 0;
FlexUtils.createSampleApp(module.getProject(), sourceRoot, mySampleAppName, myTargetPlatform, flex4);
}
catch (IOException ex) {
throw new ConfigurationException(ex.getMessage());
}
}
if (myCreateHtmlWrapperTemplate && myFlexSdk != null) {
final String path = VfsUtilCore.urlToPath(contentEntry.getUrl()) + "/" + CreateHtmlWrapperTemplateDialog.HTML_TEMPLATE_FOLDER_NAME;
if (CreateHtmlWrapperTemplateDialog.createHtmlWrapperTemplate(module.getProject(), myFlexSdk, path,
myEnableHistory, myCheckPlayerVersion, myExpressInstall)) {
bc.setUseHtmlWrapper(true);
bc.setWrapperTemplatePath(path);
}
}
if (needToCommitFlexEditor) {
flexConfigEditor.commit();
}
}
private void setupBC(final ModifiableRootModel modifiableRootModel, final ModifiableFlexBuildConfiguration bc) {
final Module module = modifiableRootModel.getModule();
bc.setName(module.getName());
bc.setTargetPlatform(myTargetPlatform);
bc.setPureAs(isPureActionScript);
bc.setOutputType(myOutputType);
final BuildConfigurationNature nature = bc.getNature();
if (myCreateSampleApp) {
final String className = FileUtil.getNameWithoutExtension(mySampleAppName);
bc.setMainClass(className);
bc.setOutputFileName(className + (myOutputType == OutputType.Library ? ".swc" : ".swf"));
if (nature.isApp()) {
if (nature.isDesktopPlatform()) {
bc.getAirDesktopPackagingOptions().setPackageFileName(className);
}
else if (nature.isMobilePlatform()) {
bc.getAndroidPackagingOptions().setEnabled(myAndroidEnabled);
bc.getAndroidPackagingOptions().setPackageFileName(className);
bc.getIosPackagingOptions().setEnabled(myIOSEnabled);
bc.getIosPackagingOptions().setPackageFileName(className);
}
}
}
else {
final String fileName = PathUtil.suggestFileName(module.getName());
bc.setOutputFileName(fileName + (myOutputType == OutputType.Library ? ".swc" : ".swf"));
if (nature.isApp()) {
if (nature.isDesktopPlatform()) {
bc.getAirDesktopPackagingOptions().setPackageFileName(fileName);
}
else if (nature.isMobilePlatform()) {
bc.getAndroidPackagingOptions().setEnabled(myAndroidEnabled);
bc.getAndroidPackagingOptions().setPackageFileName(fileName);
bc.getIosPackagingOptions().setEnabled(myIOSEnabled);
bc.getIosPackagingOptions().setPackageFileName(fileName);
}
}
}
bc.setOutputFolder(VfsUtilCore.urlToPath(modifiableRootModel.getModuleExtension(CompilerModuleExtension.class).getCompilerOutputUrl()));
bc.getDependencies().setSdkEntry(myFlexSdk != null ? Factory.createSdkEntry(myFlexSdk.getName()) : null);
if (myTargetPlayer != null) {
bc.getDependencies().setTargetPlayer(myTargetPlayer);
}
}
public static void createRunConfiguration(final Module module, final FlexBuildConfiguration bc) {
final RunManager runManager = RunManagerEx.getInstance(module.getProject());
final List<RunConfiguration> existingConfigurations = runManager.getConfigurationsList(FlashRunConfigurationType.getInstance());
for (RunConfiguration configuration : existingConfigurations) {
final FlashRunnerParameters parameters = ((FlashRunConfiguration)configuration).getRunnerParameters();
if (module.getName().equals(parameters.getModuleName()) && bc.getName().equals(parameters.getBCName())) {
//already exists
return;
}
}
final RunnerAndConfigurationSettings settings = runManager.createConfiguration("", FlashRunConfigurationType.getFactory());
final FlashRunConfiguration runConfiguration = (FlashRunConfiguration)settings.getConfiguration();
final FlashRunnerParameters params = runConfiguration.getRunnerParameters();
params.setModuleName(module.getName());
params.setBCName(bc.getName());
if (bc.getNature().isMobilePlatform()) {
if (bc.getAndroidPackagingOptions().isEnabled()) {
params.setAppDescriptorForEmulator(FlashRunnerParameters.AppDescriptorForEmulator.Android);
}
else if (bc.getIosPackagingOptions().isEnabled()) {
params.setAppDescriptorForEmulator(FlashRunnerParameters.AppDescriptorForEmulator.IOS);
}
}
settings.setName(params.suggestUniqueName(existingConfigurations));
settings.setTemporary(false);
runManager.addConfiguration(settings, false);
runManager.setSelectedConfiguration(settings);
}
@Nullable
private VirtualFile createSourceRoot(final ContentEntry contentEntry) {
final VirtualFile contentRoot = contentEntry.getFile();
if (contentRoot == null) return null;
VirtualFile sourceRoot = VfsUtil.findRelativeFile(contentRoot, "src");
if (sourceRoot == null) {
sourceRoot = ApplicationManager.getApplication().runWriteAction(new NullableComputable<VirtualFile>() {
public VirtualFile compute() {
try {
return contentRoot.createChildDirectory(this, "src");
}
catch (IOException e) {
return null;
}
}
});
}
if (sourceRoot != null) {
contentEntry.addSourceFolder(sourceRoot, false);
return sourceRoot;
}
return null;
}
@Nullable
@Override
public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) {
return new SetupFlexModuleWizardStep(this);
}
@Override
public String getParentGroup() {
return WebModuleBuilder.GROUP_NAME;
}
}