package org.jetbrains.android.run;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.sdklib.internal.avd.AvdInfo;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.actions.RunAndroidAvdManagerAction;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.sdk.AndroidSdkAdditionalData;
import org.jetbrains.android.sdk.AndroidSdkType;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.ComponentBasedErrorReporter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* @author Eugene.Kudelevsky
*/
public abstract class AvdComboBox extends ComboboxWithBrowseButton {
private final boolean myAddEmptyElement;
private final boolean myShowNotLaunchedOnly;
private final Alarm myAlarm = new Alarm(this);
private String[] myOldAvds = ArrayUtil.EMPTY_STRING_ARRAY;
public AvdComboBox(boolean addEmptyElement, boolean showNotLaunchedOnly) {
myAddEmptyElement = addEmptyElement;
myShowNotLaunchedOnly = showNotLaunchedOnly;
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final AndroidPlatform platform = findAndroidPlatform();
if (platform == null) {
Messages.showErrorDialog(AvdComboBox.this, "Cannot find any configured Android SDK");
return;
}
RunAndroidAvdManagerAction.openAvdManager();
}
});
setMinimumSize(new Dimension(100, getMinimumSize().height));
}
public void startUpdatingAvds(@NotNull ModalityState modalityState) {
if (!getComboBox().isPopupVisible()) {
doUpdateAvds();
}
addUpdatingRequest(modalityState);
}
private void addUpdatingRequest(@NotNull final ModalityState modalityState) {
if (myAlarm.isDisposed()) {
return;
}
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
startUpdatingAvds(modalityState);
}
}, 500, modalityState);
}
@Override
public void dispose() {
myAlarm.cancelAllRequests();
super.dispose();
}
private void doUpdateAvds() {
final Module module = getModule();
if (module == null || module.isDisposed()) {
return;
}
final AndroidFacet facet = AndroidFacet.getInstance(module);
final String[] newAvds;
if (facet != null) {
final Set<String> filteringSet = new HashSet<String>();
if (myShowNotLaunchedOnly) {
final AndroidDebugBridge debugBridge = AndroidSdkUtils.getDebugBridge(facet.getModule().getProject());
if (debugBridge != null) {
for (IDevice device : debugBridge.getDevices()) {
final String avdName = device.getAvdName();
if (avdName != null && avdName.length() > 0) {
filteringSet.add(avdName);
}
}
}
}
final List<String> newAvdList = new ArrayList<String>();
if (myAddEmptyElement) {
newAvdList.add("");
}
for (AvdInfo avd : facet.getAllAvds()) {
final String avdName = avd.getName();
if (!filteringSet.contains(avdName)) {
newAvdList.add(avdName);
}
}
newAvds = ArrayUtil.toStringArray(newAvdList);
}
else {
newAvds = ArrayUtil.EMPTY_STRING_ARRAY;
}
if (!Arrays.equals(myOldAvds, newAvds)) {
myOldAvds = newAvds;
final Object selected = getComboBox().getSelectedItem();
getComboBox().setModel(new DefaultComboBoxModel(newAvds));
getComboBox().setSelectedItem(selected);
}
}
@Nullable
public abstract Module getModule();
@Nullable
private AndroidPlatform findAndroidPlatform() {
AndroidPlatform platform = findAndroidPlatformFromModule();
if (platform != null) {
return platform;
}
for (Sdk sdk : ProjectJdkTable.getInstance().getAllJdks()) {
if (sdk.getSdkType() instanceof AndroidSdkType) {
final SdkAdditionalData data = sdk.getSdkAdditionalData();
if (data instanceof AndroidSdkAdditionalData) {
platform = ((AndroidSdkAdditionalData)data).getAndroidPlatform();
if (platform != null) {
return platform;
}
}
}
}
return null;
}
@Nullable
private AndroidPlatform findAndroidPlatformFromModule() {
Module module = getModule();
if (module == null) {
return null;
}
AndroidFacet facet = AndroidFacet.getInstance(module);
if (facet == null) {
return null;
}
return facet.getConfiguration().getAndroidPlatform();
}
}