package com.laex.cg2d.core.popup.actions;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import com.laex.cg2d.core.Activator;
import com.laex.cg2d.model.CGCProject;
import com.laex.cg2d.model.ScreenModel.CGEntity;
import com.laex.cg2d.model.ScreenModel.CGEntityAnimation;
import com.laex.cg2d.model.ScreenModel.CGLayer;
import com.laex.cg2d.model.ScreenModel.CGResourceFile;
import com.laex.cg2d.model.ScreenModel.CGScreenModel;
import com.laex.cg2d.model.ScreenModel.CGShape;
public class SlootProjectFixImagePaths implements IObjectActionDelegate {
private List<IProject> selectedResources;
private IWorkbenchPart targetPart;
protected int totalWork;
static class EntitiesFixer {
static class SlootProjectVisitor implements IResourceVisitor {
private IProgressMonitor monitor;
public SlootProjectVisitor(IProgressMonitor monitor) {
this.monitor = monitor;
}
@Override
public boolean visit(IResource resource) throws CoreException {
try {
if (resource.getType() != IResource.FILE) {
return true;
}
if (CGCProject.getInstance().isEntityFile((IFile) resource))
fixEntity(resource);
if (CGCProject.getInstance().isScreenFile((IFile) resource))
fixScreen(resource);
} catch (IOException e) {
Activator.log(e);
}
return true;
}
private void fixEntity(IResource resource) throws CoreException, IOException {
IFile entityFile = (IFile) resource;
CGEntity ent = CGEntity.parseFrom(entityFile.getContents());
monitor.subTask(entityFile.getName());
CGEntity.Builder entBuilder = ent.toBuilder();
for (CGEntityAnimation.Builder ea : entBuilder.getAnimationsBuilderList()) {
CGResourceFile.Builder ssFile = ea.getSpritesheetFileBuilder();
fixImagePath(ssFile);
ea.setSpritesheetFile(ssFile.build());
ssFile = ea.getFixtureFileBuilder();
fixImagePath(ssFile);
ea.setFixtureFile(ssFile.build());
ssFile = ea.getSpritesheetJsonFileBuilder();
fixImagePath(ssFile);
ea.setSpritesheetJsonFile(ssFile.build());
}
// Save
ent = entBuilder.build();
ByteArrayInputStream bais = new ByteArrayInputStream(ent.toByteArray());
entityFile.setContents(bais, true, false, new NullProgressMonitor());
monitor.worked(1);
}
private void fixScreen(IResource resource) throws CoreException, IOException {
IFile screenFile = (IFile) resource;
CGScreenModel screenModel = CGScreenModel.parseFrom(screenFile.getContents());
CGScreenModel.Builder screenModelBuilder = CGScreenModel.newBuilder(screenModel);
for (CGLayer.Builder layer : screenModelBuilder.getLayersBuilderList()) {
for (CGShape.Builder shape : layer.getShapeBuilderList()) {
CGResourceFile.Builder resBldr = shape.getEntityRefFile().toBuilder();
if (resBldr.getResourceFile().isEmpty()) {
continue;
}
fixImagePath(resBldr);
shape.setEntityRefFile(resBldr.build());
}
}
screenModel = screenModelBuilder.build();
// Save
ByteArrayInputStream bais = new ByteArrayInputStream(screenModel.toByteArray());
screenFile.setContents(bais, true, false, new NullProgressMonitor());
}
private void fixImagePath(CGResourceFile.Builder ssFile) {
if (ssFile.getResourceFile().isEmpty()) {
return;
}
IPath p = new Path(ssFile.getResourceFile());
IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(p);
ssFile.setResourceFileAbsolute(f.getLocation().toString());
Activator.log("Fixed image path - " + ssFile.getResourceFileAbsolute());
}
}
public static void fix(IProgressMonitor monitor, List<IProject> projects) throws CoreException {
SlootProjectVisitor spv = new EntitiesFixer.SlootProjectVisitor(monitor);
for (IProject p : projects) {
p.accept(spv);
}
}
}
public SlootProjectFixImagePaths() {
}
@Override
public void run(IAction action) {
if (selectedResources.size() <= 0) {
return;
}
ProgressMonitorDialog pmd = new ProgressMonitorDialog(this.targetPart.getSite().getShell());
try {
calculateWork();
pmd.run(false, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Fixing absolute paths", totalWork);
try {
SlootProjectFixImagePaths.EntitiesFixer.fix(monitor, selectedResources);
} catch (CoreException e) {
Activator.log(e);
}
monitor.done();
}
});
} catch (InvocationTargetException e) {
Activator.log(e);
} catch (InterruptedException e) {
Activator.log(e);
} catch (CoreException e1) {
Activator.log(e1);
}
}
private void calculateWork() throws CoreException {
for (IProject p : selectedResources) {
p.accept(new IResourceVisitor() {
@Override
public boolean visit(IResource resource) throws CoreException {
if (resource.getType() == IResource.FILE) {
if (CGCProject.getInstance().isEntityFile((IFile) resource)) {
totalWork++;
}
if (CGCProject.getInstance().isScreenFile((IFile) resource)) {
totalWork++;
}
}
return false;
}
});
}
}
@Override
public void selectionChanged(IAction action, ISelection selection) {
IStructuredSelection strucSel = (IStructuredSelection) selection;
selectedResources = (List<IProject>) strucSel.toList();
}
@Override
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
this.targetPart = targetPart;
}
}