/*
* Created on 28-May-2006
*
* Copyright (c) 2006 P.J.Leonard
*
* http://www.frinika.com
*
* This file is part of Frinika.
*
* Frinika is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Frinika is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Frinika; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.frinika.sequencer.model;
import com.frinika.project.ProjectContainer;
/**
* Action to split selected parts at a given tick.
*
* @author Paul
*
*/
public class GluePartEditAction implements EditHistoryAction {
ProjectContainer project;
MidiPart origPart1;
MidiPart origPart2 = null;
MidiPart newPart = null;
public GluePartEditAction(MidiPart part) {
origPart1 = part;
project = part.getLane().getProject();
}
public void undo() {
if (newPart == null)
return;
newPart.commitEventsRemove();
newPart.lane.parts.remove(newPart);
origPart1.lane.parts.add(origPart1);
origPart1.commitEventsAdd();
origPart2.lane.parts.add(origPart2);
origPart2.commitEventsAdd();
project.getPartSelection().removeSelected(newPart);
}
public void redo() {
if (newPart == null) {
origPart2 = findNearest(origPart1);
if (origPart2 == null) {
System.out
.println(" Need at least 2 parts in the lane to use glue");
return;
}
newPart = new MidiPart((MidiLane) origPart1.getLane());
newPart.setStartTick(Math.min(origPart1.getStartTick(),
origPart2.getStartTick()));
newPart.setEndTick(Math.max(origPart1.getEndTick(), origPart2.getEndTick()));
for (MultiEvent ev : origPart1.getMultiEvents()) {
MultiEvent eNew = (MultiEvent) ev.deepCopy(newPart);
newPart.getMultiEvents().add(eNew);
}
for (MultiEvent ev : origPart2.getMultiEvents()) {
MultiEvent eNew = (MultiEvent) ev.deepCopy(newPart);
newPart.getMultiEvents().add(eNew);
}
} else {
// newPart.lane.parts.add(newPart);
}
origPart1.commitEventsRemove();
origPart1.lane.parts.remove(origPart1);
origPart2.commitEventsRemove();
origPart2.lane.parts.remove(origPart2);
newPart.commitEventsAdd();
project.getPartSelection().removeSelected(origPart1);
project.getPartSelection().removeSelected(origPart2);
}
MidiPart findNearest(Part ref) {
long dist = Long.MAX_VALUE;
long start = ref.getStartTick();
Part part2 = null;
for (Part part : ref.getLane().getParts()) {
if (part == ref)
continue;
long end2 = part.getEndTick();
long start2 = part.getStartTick();
if (start2 < start) {
long dist2 = end2 - start;
if (Math.abs(dist2) < dist) {
part2 = part;
dist = Math.abs(dist2);
}
}
}
return (MidiPart) part2;
}
}