text: package krasa.formatter.settings;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  
  import org.apache.commons.beanutils.BeanUtils;
  import org.jetbrains.annotations.NotNull;
  
  import com.intellij.openapi.application.ApplicationManager;
  import com.intellij.openapi.application.PathManager;
  import com.intellij.openapi.components.*;
  import com.intellij.openapi.project.Project;
  import com.intellij.util.xmlb.XmlSerializerUtil;
  
  import krasa.formatter.plugin.Notifier;
  import krasa.formatter.utils.ProjectUtils;
  import krasa.formatter.utils.StringUtils;
  
  /**
   * @author Vojtech Krasa
   */
  @State(name = "EclipseCodeFormatterSettings", storages = {
  		@Storage(file = "$APP_CONFIG$/eclipseCodeFormatter.xml") })
  public class GlobalSettings
  		implements ApplicationComponent, PersistentStateComponent<GlobalSettings>, ExportableApplicationComponent {
  	private List<Settings> settingsList = new ArrayList<Settings>();
  	private List<Long> deletedSettingsId = new ArrayList<Long>();
  
  	public static GlobalSettings getInstance() {
  		return ApplicationManager.getApplication().getComponent(GlobalSettings.class);
  	}
  
  	@Override
  	public GlobalSettings getState() {
  		return this;
  	}
  
  	@Override
  	public void loadState(GlobalSettings state) {
  		XmlSerializerUtil.copyBean(state, this);
  	}
  
  	public List<Settings> getSettingsList() {
  		return settingsList;
  	}
  
  	public void setSettingsList(List<Settings> settingsList) {
  		this.settingsList = settingsList;
  	}
  
  	public Settings newSettings() {
  		String name = StringUtils.generateName(settingsList, 1, "new");
  		Settings aNew = new Settings(generateId(), name);
  		settingsList.add(aNew);
  		return aNew;
  	}
  
  	public Settings copySettings(Project project, Settings settings) {
  		Settings newSettings = clone(settings);
  		if (settings.isProjectSpecific()) {
  			newSettings.setName(StringUtils.generateName(settingsList, 1, project.getName(), project.getName()));
  		} else {
  			newSettings.setName(settings.getName() + " copy");
  		}
  		newSettings.setId(generateId());
  		settingsList.add(newSettings);
  		return newSettings;
  	}
  
  	public static Settings clone(Settings settings) {
  		Settings newSettings = new Settings();
  		try {
  			BeanUtils.copyProperties(newSettings, settings);
  		} catch (Exception e) {
  			throw new RuntimeException(e);
  		}
  		return newSettings;
  	}
  
  	public void updateSettings(Settings settings, Project project) {
  		if (settings.getId() == null) {
  			addToGlobalSettings(settings, project);
  		} else {
  			for (Settings settings1 : settingsList) {
  				if (settings1.getId().equals(settings.getId())) {
  					XmlSerializerUtil.copyBean(settings, settings1);
  				}
  			}
  		}
  	}
  	private void addToGlobalSettings(@NotNull Settings newSettings, @NotNull Project project) {
  		if (newSettings.getId() == null) {
  			newSettings.setId(generateId());
  		}
  		if (newSettings.getName() == null) {
  			String name = StringUtils.generateName(settingsList, 1, project.getName(), project.getName());
  			newSettings.setName(name);
  		}
  		settingsList.add(newSettings);
  	}
  
  	private Long generateId() {
  		long newId = new Date().getTime();
  		for (Settings settings : settingsList) {
  			if (settings.getId().equals(newId)) {
  				newId = generateId();
  			}
  		}
  		return newId;
  	}
  
  	@NotNull
  	public Settings getGlobalProfile(@NotNull Settings state, @NotNull Project project) throws DeletedProfileException {
  		if (state.isNotSaved()) {
  			addToGlobalSettings(state, project);
  			return state;
  		} else {
  			for (Settings settings : settingsList) {
  				if (settings.getId().equals(state.getId())) {
  					return settings;
  				}
  			}
  			for (Settings settings : settingsList) {
  				if (settings.getName().equals(state.getName())) {
  					return settings;
  				}
  			}
  			if (deletedSettingsId.contains(state.getId())) {
  				Notifier.notifyDeletedSettings(project);
  				throw new DeletedProfileException();
  			}
  			addToGlobalSettings(state, project);
  			return state;
  		}
  	}
  
  	@Override
  	public void initComponent() {
  	}
  
  	@Override
  	public void disposeComponent() {
  	}
  
  	@NotNull
  	@Override
  	public String getComponentName() {
  		return "EclipseCodeFormatterGlobalSettings";
  	}
  
  	@NotNull
  	@Override
  	public File[] getExportFiles() {
  		return new File[] { PathManager.getOptionsFile("eclipseCodeFormatter") };
  	}
  
  	@NotNull
  	@Override
  	public String getPresentableName() {
  		return "Eclipse Code Formatter";
  	}
  
  	public void delete(Settings settings, Project project) {
  		settingsList.remove(settings);
  		deletedSettingsId.add(settings.getId());
  		ProjectUtils.notifyProjectsWhichUsesThisSettings(settings, project);
  	}
  
  }
  