1 /*
2  * Created on 23-nov-2005
3  *
4  * TODO To change the template for this generated file go to
5  * Window - Preferences - Java - Code Style - Code Templates
6  */
7 package org.herac.tuxguitar.song.managers;
8 
9 import java.util.ArrayList;
10 import java.util.Iterator;
11 import java.util.List;
12 
13 import org.herac.tuxguitar.song.factory.TGFactory;
14 import org.herac.tuxguitar.song.models.TGChannel;
15 import org.herac.tuxguitar.song.models.TGColor;
16 import org.herac.tuxguitar.song.models.TGDuration;
17 import org.herac.tuxguitar.song.models.TGMarker;
18 import org.herac.tuxguitar.song.models.TGMeasure;
19 import org.herac.tuxguitar.song.models.TGMeasureHeader;
20 import org.herac.tuxguitar.song.models.TGSong;
21 import org.herac.tuxguitar.song.models.TGString;
22 import org.herac.tuxguitar.song.models.TGTempo;
23 import org.herac.tuxguitar.song.models.TGTimeSignature;
24 import org.herac.tuxguitar.song.models.TGTrack;
25 
26 
27 /**
28  * @author julian
29  *
30  * TODO To change the template for this generated type comment go to
31  * Window - Preferences - Java - Code Style - Code Templates
32  */
33 public class TGSongManager {
34 	public static final short MAX_CHANNELS = 16;
35 
36 	private TGFactory factory;
37 	private TGSong song;
38 	private TGTrackManager trackManager;
39 	private TGMeasureManager measureManager;
40 
TGSongManager()41 	public TGSongManager(){
42 		this(new TGFactory());
43 	}
44 
TGSongManager(TGFactory factory)45 	public TGSongManager(TGFactory factory){
46 		this.factory = factory;
47 	}
48 
getFactory()49 	public TGFactory getFactory(){
50 		return this.factory;
51 	}
52 
setFactory(TGFactory factory)53 	public void setFactory(TGFactory factory){
54 		this.factory = factory;
55 	}
56 
getTrackManager()57 	public TGTrackManager getTrackManager(){
58 		if(this.trackManager == null){
59 			this.trackManager = new TGTrackManager(this);
60 		}
61 		return this.trackManager;
62 	}
63 
getMeasureManager()64 	public TGMeasureManager getMeasureManager(){
65 		if(this.measureManager == null){
66 			this.measureManager = new TGMeasureManager(this);
67 		}
68 		return this.measureManager;
69 	}
70 
setSongName(String name)71 	public void setSongName(String name){
72 		getSong().setName(name);
73 	}
74 
getSong()75 	public TGSong getSong(){
76 		return this.song;
77 	}
78 
clearSong()79 	public void clearSong(){
80 		if(this.getSong() != null){
81 			this.getSong().clear();
82 		}
83 	}
84 
setSong(TGSong song)85 	public void setSong(TGSong song){
86 		if(song != null){
87 			this.clearSong();
88 			this.song = song;
89 		}
90 	}
91 
setProperties(String name,String artist,String album,String author,String date,String copyright,String writer,String transcriber,String comments)92 	public void setProperties(String name,String artist,String album,String author,String date,String copyright,String writer,String transcriber,String comments){
93 		getSong().setName(name);
94 		getSong().setArtist(artist);
95 		getSong().setAlbum(album);
96 		getSong().setAuthor(author);
97 		getSong().setDate(date);
98 		getSong().setCopyright(copyright);
99 		getSong().setWriter(writer);
100 		getSong().setTranscriber(transcriber);
101 		getSong().setComments(comments);
102 	}
103 
addTrack(TGTrack trackToAdd)104 	public void addTrack(TGTrack trackToAdd){
105 		this.orderTracks();
106 		int addIndex = -1;
107 		for(int i = 0;i < getSong().countTracks();i++){
108 			TGTrack track = getSong().getTrack(i);
109 			if(addIndex == -1 && track.getNumber() == trackToAdd.getNumber()){
110 				addIndex = i;
111 			}
112 			if(addIndex >= 0){
113 				track.setNumber(track.getNumber() + 1);
114 			}
115 		}
116 		if(addIndex < 0){
117 			addIndex = getSong().countTracks();
118 		}
119 		getSong().addTrack(addIndex,trackToAdd);
120 	}
121 
removeTrack(int number)122 	public void removeTrack(int number){
123 		int nextNumber = number;
124 		TGTrack trackToRemove = null;
125 		orderTracks();
126 		Iterator it = getSong().getTracks();
127 		while(it.hasNext()){
128 			TGTrack currTrack = (TGTrack)it.next();
129 			if(trackToRemove == null && currTrack.getNumber() == nextNumber){
130 				trackToRemove = currTrack;
131 			}else if(currTrack.getNumber() == (nextNumber + 1)){
132 				currTrack.setNumber(nextNumber);
133 				nextNumber ++;
134 			}
135 
136 		}
137 		getSong().removeTrack(trackToRemove);
138 	}
139 
orderTracks()140 	private void orderTracks(){
141 		for(int i = 0;i < getSong().countTracks();i++){
142 			TGTrack minTrack = null;
143 			for(int trackIdx = i;trackIdx < getSong().countTracks();trackIdx++){
144 				TGTrack track = getSong().getTrack(trackIdx);
145 				if(minTrack == null || track.getNumber() < minTrack.getNumber()){
146 					minTrack = track;
147 				}
148 			}
149 			getSong().moveTrack(i,minTrack);
150 		}
151 	}
152 
newSong()153 	public TGSong newSong(){
154 		TGSong song = getFactory().newSong();
155 
156 		TGMeasureHeader header = getFactory().newHeader();
157 		header.setNumber(1);
158 		header.setStart(TGDuration.QUARTER_TIME);
159 		header.getTimeSignature().setNumerator(4);
160 		header.getTimeSignature().getDenominator().setValue(TGDuration.QUARTER);
161 		song.addMeasureHeader(header);
162 
163 		TGMeasure measure = getFactory().newMeasure(header);
164 
165 		TGTrack track = getFactory().newTrack();
166 		track.setNumber(1);
167 		track.setName("Track 1");
168 		track.addMeasure(measure);
169 		track.getChannel().setChannel((short)0);
170 		track.getChannel().setEffectChannel((short)1);
171 		track.setStrings(createDefaultInstrumentStrings());
172 		TGColor.RED.copy(track.getColor());
173 		song.addTrack(track);
174 
175 		return song;
176 	}
177 
getNextTrackNumber()178 	public int getNextTrackNumber(){
179 		return (getSong().countTracks() + 1);
180 	}
181 
getFreeChannel(short instrument,boolean isPercussion)182 	public TGChannel getFreeChannel(short instrument,boolean isPercussion){
183 		if(isPercussion){
184 			return TGChannel.newPercussionChannel(getFactory());
185 		}
186 		short normalChannel = -1;
187 		short effectChannel = -1;
188 
189 		boolean[] usedChannels = getUsedChannels();
190 		boolean[] usedEffectChannels = getUsedEffectChannels();
191 		for(short i = 0;i < MAX_CHANNELS;i++){
192 			if(!TGChannel.isPercussionChannel(i) && !usedChannels[i] && !usedEffectChannels[i]){
193 				normalChannel = (normalChannel < 0)?i:normalChannel;
194 				effectChannel = (effectChannel < 0 && i != normalChannel)?i:effectChannel;
195 			}
196 		}
197 		if(normalChannel < 0 || effectChannel < 0){
198 			if(normalChannel >= 0 ){
199 				effectChannel = normalChannel;
200 			}else{
201 				TGChannel songChannel = getLastTrack().getChannel();
202 				return songChannel.clone(getFactory());
203 			}
204 		}
205 		TGChannel channel = getFactory().newChannel();
206 		channel.setChannel(normalChannel);
207 		channel.setEffectChannel(effectChannel);
208 		channel.setInstrument(instrument);
209 		return channel;
210 	}
211 
getUsedEffectChannels()212 	public boolean[] getUsedEffectChannels(){
213 		boolean[] channels = new boolean[MAX_CHANNELS];
214 		for(int i = 0;i < getSong().countTracks();i++){
215 			TGTrack track = getSong().getTrack(i);
216 			channels[track.getChannel().getEffectChannel()] = true;
217 		}
218 		return channels;
219 	}
220 
getUsedChannels()221 	public boolean[] getUsedChannels(){
222 		boolean[] channels = new boolean[MAX_CHANNELS];
223 		for(int i = 0;i < getSong().countTracks();i++){
224 			TGTrack track = getSong().getTrack(i);
225 			channels[track.getChannel().getChannel()] = true;
226 		}
227 		return channels;
228 	}
229 
getUsedChannel(int channel)230 	public TGChannel getUsedChannel(int channel){
231 		for(int i = 0;i < getSong().countTracks();i++){
232 			TGTrack track = getSong().getTrack(i);
233 			if(channel == track.getChannel().getChannel()){
234 				return track.getChannel().clone(getFactory());
235 			}
236 		}
237 		return null;
238 	}
239 
countTracksForChannel(int channel)240 	public int countTracksForChannel(int channel){
241 		int count = 0;
242 		for(int i = 0;i < getSong().countTracks();i++){
243 			TGTrack track = getSong().getTrack(i);
244 			if(channel == track.getChannel().getChannel()){
245 				count ++;
246 			}
247 		}
248 		return count;
249 	}
250 
updateChannel(TGChannel channel)251 	public void updateChannel(TGChannel channel){
252 		for(int i = 0;i < getSong().countTracks();i++){
253 			TGTrack track = getSong().getTrack(i);
254 			if(channel.getChannel() == track.getChannel().getChannel()){
255 				track.setChannel(channel.clone(getFactory()));
256 			}
257 		}
258 	}
259 
getTrack(int number)260 	public TGTrack getTrack(int number){
261 		TGTrack track = null;
262 		for (int i = 0; i < getSong().countTracks(); i++) {
263 			TGTrack currTrack = getSong().getTrack(i);
264 			if(currTrack.getNumber() == number){
265 				track = currTrack;
266 				break;
267 			}
268 		}
269 		return track;
270 	}
271 
getFirstTrack()272 	public TGTrack getFirstTrack(){
273 		TGTrack track = null;
274 		if(!getSong().isEmpty()){
275 			track = getSong().getTrack(0);
276 		}
277 		return track;
278 	}
279 
getLastTrack()280 	public TGTrack getLastTrack(){
281 		TGTrack track = null;
282 		if(!getSong().isEmpty()){
283 			track = getSong().getTrack(getSong().countTracks() - 1);
284 		}
285 		return track;
286 	}
287 
cloneTrack(TGTrack track)288 	public TGTrack cloneTrack(TGTrack track){
289 		TGTrack clone = track.clone(getFactory(),getSong());
290 		clone.setNumber(getNextTrackNumber());
291 		addTrack(clone);
292 		return clone;
293 	}
294 
moveTrackUp(TGTrack track)295 	public boolean moveTrackUp(TGTrack track){
296 		if(track.getNumber() > 1){
297 			TGTrack prevTrack = getTrack(track.getNumber() - 1);
298 			prevTrack.setNumber(prevTrack.getNumber() + 1);
299 			track.setNumber(track.getNumber() - 1);
300 			orderTracks();
301 			return true;
302 		}
303 		return false;
304 	}
305 
moveTrackDown(TGTrack track)306 	public boolean moveTrackDown(TGTrack track){
307 		if(track.getNumber() < getSong().countTracks()){
308 			TGTrack nextTrack = getTrack(track.getNumber() + 1);
309 			nextTrack.setNumber(nextTrack.getNumber() - 1);
310 			track.setNumber(track.getNumber() + 1);
311 			orderTracks();
312 			return true;
313 		}
314 		return false;
315 	}
316 
makeNewTrack()317 	private TGTrack makeNewTrack(){
318 		TGTrack track = getFactory().newTrack();
319 		track.setNumber(getNextTrackNumber());
320 		track.setName("Track " + track.getNumber());
321 		//measures
322 		Iterator it = getSong().getMeasureHeaders();
323 		while(it.hasNext()){
324 			TGMeasureHeader header = (TGMeasureHeader)it.next();
325 			TGMeasure measure = getFactory().newMeasure(header);
326 			track.addMeasure(measure);
327 		}
328 		track.setStrings(createDefaultInstrumentStrings());
329 		getFreeChannel(TGChannel.DEFAULT_INSTRUMENT,false).copy(track.getChannel());
330 		TGColor.RED.copy(track.getColor());
331 		return track;
332 	}
333 
createTrack()334 	public TGTrack createTrack(){
335 		if(getSong().isEmpty()){
336 			setSong(newSong());
337 			return getLastTrack();
338 		}
339 		TGTrack track = makeNewTrack();
340 		addTrack(track);
341 		return track;
342 	}
343 
removeTrack(TGTrack track)344 	public void removeTrack(TGTrack track){
345 		removeTrack(track.getNumber());
346 	}
347 
changeTimeSignature(long start,TGTimeSignature timeSignature,boolean toEnd)348 	public void changeTimeSignature(long start,TGTimeSignature timeSignature,boolean toEnd){
349 		changeTimeSignature(getMeasureHeaderAt(start),timeSignature,toEnd);
350 	}
351 
changeTimeSignature(TGMeasureHeader header,TGTimeSignature timeSignature,boolean toEnd)352 	public void changeTimeSignature(TGMeasureHeader header,TGTimeSignature timeSignature,boolean toEnd){
353 		//asigno el nuevo ritmo
354 		timeSignature.copy(header.getTimeSignature());
355 
356 		long nextStart = header.getStart() + header.getLength();
357 		List measures = getMeasureHeadersBeforeEnd(header.getStart() + 1);
358 		Iterator it = measures.iterator();
359 		while(it.hasNext()){
360 			TGMeasureHeader nextHeader = (TGMeasureHeader)it.next();
361 
362 			long theMove = nextStart - nextHeader.getStart();
363 
364 			//moveMeasureComponents(nextHeader,theMove);
365 			moveMeasureHeader(nextHeader,theMove,0);
366 
367 			if(toEnd){
368 				timeSignature.copy(nextHeader.getTimeSignature());
369 			}
370 			nextStart = nextHeader.getStart() + nextHeader.getLength();
371 		}
372 		moveOutOfBoundsBeatsToNewMeasure(header.getStart());
373 	}
374 
moveOutOfBoundsBeatsToNewMeasure(long start)375 	public void moveOutOfBoundsBeatsToNewMeasure(long start){
376 		Iterator it = getSong().getTracks();
377 		while( it.hasNext() ){
378 			TGTrack track = (TGTrack) it.next();
379 			getTrackManager().moveOutOfBoundsBeatsToNewMeasure(track, start);
380 		}
381 	}
382 
383 	/*
384 	public void changeTimeSignature(TGMeasureHeader header,TGTimeSignature timeSignature,boolean toEnd){
385 		//asigno el nuevo ritmo
386 		timeSignature.copy(header.getTimeSignature());
387 
388 		long nextStart = header.getStart() + header.getLength();
389 		List measures = getMeasureHeadersBeforeEnd(header.getStart() + 1);
390 		Iterator it = measures.iterator();
391 		while(it.hasNext()){
392 			TGMeasureHeader nextHeader = (TGMeasureHeader)it.next();
393 
394 			long theMove = nextStart - nextHeader.getStart();
395 
396 			moveMeasureComponents(nextHeader,theMove);
397 			moveMeasureHeader(nextHeader,theMove,0);
398 
399 			if(toEnd){
400 				timeSignature.copy(nextHeader.getTimeSignature());
401 			}
402 			nextStart = nextHeader.getStart() + nextHeader.getLength();
403 		}
404 	}
405 	*/
changeTripletFeel(long start,int tripletFeel,boolean toEnd)406 	public void changeTripletFeel(long start,int tripletFeel,boolean toEnd){
407 		changeTripletFeel(getMeasureHeaderAt(start),tripletFeel,toEnd);
408 	}
409 
changeTripletFeel(TGMeasureHeader header,int tripletFeel,boolean toEnd)410 	public void changeTripletFeel(TGMeasureHeader header,int tripletFeel,boolean toEnd){
411 		//asigno el nuevo tripletFeel
412 		header.setTripletFeel(tripletFeel);
413 
414 		if(toEnd){
415 			List measures = getMeasureHeadersBeforeEnd(header.getStart() + 1);
416 			Iterator it = measures.iterator();
417 			while(it.hasNext()){
418 				TGMeasureHeader nextHeader = (TGMeasureHeader)it.next();
419 				nextHeader.setTripletFeel(tripletFeel);
420 			}
421 		}
422 	}
423 
changeTempos(long start,TGTempo tempo,boolean toEnd)424 	public void changeTempos(long start,TGTempo tempo,boolean toEnd){
425 		changeTempos(getMeasureHeaderAt(start),tempo,toEnd);
426 	}
427 
changeTempos(TGMeasureHeader header,TGTempo tempo,boolean toEnd)428 	public void changeTempos(TGMeasureHeader header,TGTempo tempo,boolean toEnd){
429 		int oldValue = header.getTempo().getValue();
430 		Iterator it = getMeasureHeadersAfter(header.getNumber() - 1).iterator();
431 		while(it.hasNext()){
432 			TGMeasureHeader nextHeader = (TGMeasureHeader)it.next();
433 			if(toEnd || nextHeader.getTempo().getValue() == oldValue){
434 				changeTempo(nextHeader,tempo);
435 			}else{
436 				break;
437 			}
438 		}
439 	}
440 
changeTempo(TGMeasureHeader header,TGTempo tempo)441 	public void changeTempo(TGMeasureHeader header,TGTempo tempo){
442 		tempo.copy(header.getTempo());
443 	}
444 
changeOpenRepeat(long start)445 	public void changeOpenRepeat(long start){
446 		TGMeasureHeader header = getMeasureHeaderAt(start);
447 		header.setRepeatOpen(!header.isRepeatOpen());
448 	}
449 
changeCloseRepeat(long start,int repeatClose)450 	public void changeCloseRepeat(long start,int repeatClose){
451 		TGMeasureHeader header = getMeasureHeaderAt(start);
452 		header.setRepeatClose(repeatClose);
453 	}
454 
changeAlternativeRepeat(long start,int repeatAlternative)455 	public void changeAlternativeRepeat(long start,int repeatAlternative){
456 		TGMeasureHeader header = getMeasureHeaderAt(start);
457 		header.setRepeatAlternative(repeatAlternative);
458 	}
459 
addNewMeasureBeforeEnd()460 	public TGMeasureHeader addNewMeasureBeforeEnd(){
461 		TGMeasureHeader lastHeader = getLastMeasureHeader();
462 		TGMeasureHeader header = getFactory().newHeader();
463 		header.setNumber((lastHeader.getNumber() + 1));
464 		header.setStart((lastHeader.getStart() + lastHeader.getLength()));
465 		header.setRepeatOpen(false);
466 		header.setRepeatClose(0);
467 		header.setTripletFeel(lastHeader.getTripletFeel());
468 		lastHeader.getTimeSignature().copy(header.getTimeSignature());
469 		lastHeader.getTempo().copy(header.getTempo());
470 		getSong().addMeasureHeader(header);
471 
472 		Iterator it = getSong().getTracks();
473 		while(it.hasNext()){
474 			TGTrack track = (TGTrack)it.next();
475 			getTrackManager().addNewMeasureBeforeEnd(track,header);
476 		}
477 		return header;
478 	}
479 
addNewMeasure(int number)480 	public void addNewMeasure(int number){
481 		//Obtengo un clon para el nuevo Header.
482 		TGMeasureHeader header = null;
483 		if(number == 1){
484 			header = getMeasureHeader(number).clone(getFactory());
485 		}else{
486 			header = getMeasureHeader((number - 1)).clone(getFactory());
487 			header.setStart(header.getStart() + header.getLength());
488 			header.setNumber(header.getNumber() + 1);
489 		}
490 		header.setMarker(null);
491 		header.setRepeatOpen(false);
492 		header.setRepeatAlternative(0);
493 		header.setRepeatClose(0);
494 
495 		//Si hay Headers siguientes los muevo
496 		TGMeasureHeader nextHeader = getMeasureHeader(number);
497 		if(nextHeader != null){
498 			moveMeasureHeaders(getMeasureHeadersBeforeEnd(nextHeader.getStart()),header.getLength(),1,true);
499 		}
500 
501 		//Agrego el header a la lista
502 		addMeasureHeader( (header.getNumber() - 1) ,header);
503 
504 		//Agrego los compases en todas las pistas
505 		Iterator it = getSong().getTracks();
506 		while(it.hasNext()){
507 			TGTrack track = (TGTrack)it.next();
508 			getTrackManager().addNewMeasure(track,header);
509 		}
510 	}
511 
getMeasures(long start)512 	public List getMeasures(long start){
513 		List measures = new ArrayList();
514 		Iterator it = getSong().getTracks();
515 		while(it.hasNext()){
516 			TGTrack track = (TGTrack)it.next();
517 			TGMeasure measure = getTrackManager().getMeasureAt(track,start);
518 			if(measure != null){
519 				measures.add(measure);
520 			}
521 		}
522 		return measures;
523 	}
524 
replaceTrack(TGTrack track)525 	public TGTrack replaceTrack(TGTrack track){
526 		TGTrack current = getTrack(track.getNumber());
527 		if(current != null){
528 			track.copy(getFactory(), getSong(), current);
529 		}
530 		return current;
531 	}
532 	/*
533 	public TGSongSegment copyMeasures(int m1, int m2){
534 		TGSongSegment segment = new TGSongSegment();
535 		int number1 = Math.max(1,m1);
536 		int number2 = Math.min(getSong().countMeasureHeaders(),m2);
537 		for(int number = number1; number <= number2;number ++){
538 			segment.getHeaders().add( getMeasureHeader(number) );
539 		}
540 		Iterator it = getSong().getTracks();
541 		while(it.hasNext()){
542 			TGTrack track = (TGTrack)it.next();
543 			List measures = getTrackManager().copyMeasures(track,number1,number2);
544 			segment.addTrack(track.getNumber(),measures);
545 		}
546 		return segment.clone(getFactory());
547 	}
548 
549 	public TGSongSegment copyMeasures(int m1, int m2,TGTrack track){
550 		TGSongSegment segment = new TGSongSegment();
551 		int number1 = Math.max(1,m1);
552 		int number2 = Math.min(getSong().countMeasureHeaders(),m2);
553 		for(int number = number1; number <= number2;number ++){
554 			segment.getHeaders().add( getMeasureHeader(number) );
555 		}
556 		List measures = getTrackManager().copyMeasures(track,number1,number2);
557 		segment.addTrack(track.getNumber(),measures);
558 
559 		return segment.clone(getFactory());
560 	}
561 
562 	public void insertMeasures(TGSongSegment segment,int fromNumber,long move){
563 		List headers = new ArrayList();
564 		moveMeasureHeaders(segment.getHeaders(),move,0,false);
565 
566 		int headerNumber = fromNumber;
567 		Iterator it = segment.getHeaders().iterator();
568 		while(it.hasNext()){
569 			TGMeasureHeader header = (TGMeasureHeader)it.next();
570 			header.setNumber(headerNumber);
571 			headers.add(header);
572 			headerNumber ++;
573 		}
574 		long start = ((TGMeasureHeader)headers.get(0)).getStart();
575 		long end = ((TGMeasureHeader)headers.get(headers.size() - 1)).getStart() + ((TGMeasureHeader)headers.get(headers.size() - 1)).getLength();
576 		List headersBeforeEnd = getMeasureHeadersBeforeEnd(start);
577 		moveMeasureHeaders(headersBeforeEnd,end - start,headers.size(),true);
578 
579 		it = segment.getHeaders().iterator();
580 		while(it.hasNext()){
581 			TGMeasureHeader header = (TGMeasureHeader)it.next();
582 			addMeasureHeader(header.getNumber() - 1,header);
583 		}
584 
585 		it = getSong().getTracks();
586 		while (it.hasNext()) {
587 			TGTrack currTrack = (TGTrack) it.next();
588 			List measures = null;
589 
590 			Iterator tracks = segment.getTracks().iterator();
591 			while(tracks.hasNext()){
592 				TGTrackSegment tSegment = (TGTrackSegment)tracks.next();
593 				if(tSegment.getTrack() == currTrack.getNumber()){
594 					measures = tSegment.getMeasures();
595 					break;
596 				}
597 			}
598 			if(measures == null){
599 				measures = getEmptyMeasures(((TGTrackSegment)segment.getTracks().get(0)).getMeasures());
600 			}
601 
602 			for(int i = 0;i < measures.size();i++){
603 				TGMeasure measure = (TGMeasure)measures.get(i);
604 				measure.setHeader((TGMeasureHeader)headers.get(i));
605 				getMeasureManager().moveAllComponents(measure,move);
606 			}
607 			getTrackManager().insertMeasures(currTrack,measures);
608 		}
609 	}
610 
611 	private List getEmptyMeasures(List measures) {
612 		List emptyMeasures = new ArrayList();
613 
614 		Iterator it = measures.iterator();
615 		while (it.hasNext()) {
616 			TGMeasure measure = (TGMeasure) it.next();
617 			TGMeasure emptyMeasure = getFactory().newMeasure(null);
618 			emptyMeasure.setClef(measure.getClef());
619 			emptyMeasure.setKeySignature(measure.getKeySignature());
620 			emptyMeasures.add(emptyMeasure);
621 		}
622 		return emptyMeasures;
623 	}
624 	*/
625 	/*
626 	public void replaceMeasures(TGSongSegment tracksMeasures,long move) {
627 		List measureHeaders = new ArrayList();
628 		moveMeasureHeaders(tracksMeasures.getHeaders(),move,0,false);
629 		Iterator it = tracksMeasures.getHeaders().iterator();
630 		while(it.hasNext()){
631 			TGMeasureHeader header = (TGMeasureHeader)it.next();
632 			TGMeasureHeader replace = replaceMeasureHeader(header);
633 
634 			Iterator nextHeaders = getMeasureHeadersAfter(replace.getNumber()).iterator();
635 			long nextStart =  (replace.getStart() + replace.getLength());
636 			while(nextHeaders.hasNext()){
637 				TGMeasureHeader next = (TGMeasureHeader)nextHeaders.next();
638 				moveMeasureComponents(next, (nextStart - next.getStart() ));
639 				moveMeasureHeader(next, (nextStart - next.getStart() ) , 0);
640 				nextStart = (next.getStart() + next.getLength());
641 			}
642 			measureHeaders.add(replace);
643 		}
644 
645 		it = tracksMeasures.getTracks().iterator();
646 		while(it.hasNext()){
647 			TGTrackSegment trackMeasure = (TGTrackSegment)it.next();
648 
649 			TGTrack currTrack = getTrack(trackMeasure.getTrack());
650 			List measures = trackMeasure.getMeasures();
651 			for(int i = 0;i < measures.size();i++){
652 				TGMeasure measure = (TGMeasure)measures.get(i);
653 				measure.setHeader((TGMeasureHeader)measureHeaders.get(i));
654 				getMeasureManager().moveAllComponents(measure,move);
655 				getTrackManager().replaceMeasure(currTrack,measure);
656 			}
657 		}
658 	}
659 	*/
getFirstMeasureHeader()660 	public TGMeasureHeader getFirstMeasureHeader(){
661 		TGMeasureHeader firstHeader = null;
662 		for(int i = 0;i < getSong().countMeasureHeaders();i++){
663 			TGMeasureHeader currHeader = getSong().getMeasureHeader(i);
664 			if(firstHeader == null || (currHeader.getStart() < firstHeader.getStart())){
665 				firstHeader = currHeader;
666 			}
667 		}
668 		return firstHeader;
669 	}
670 
getLastMeasureHeader()671 	public TGMeasureHeader getLastMeasureHeader(){
672 		int lastIndex = getSong().countMeasureHeaders() - 1;
673 		return getSong().getMeasureHeader(lastIndex);
674 	}
675 
getPrevMeasureHeader(TGMeasureHeader header)676 	public TGMeasureHeader getPrevMeasureHeader(TGMeasureHeader header){
677 		int prevIndex = header.getNumber() - 1;
678 		if(prevIndex > 0){
679 			return getSong().getMeasureHeader(prevIndex - 1);
680 		}
681 		return null;
682 	}
683 
getNextMeasureHeader(TGMeasureHeader header)684 	public TGMeasureHeader getNextMeasureHeader(TGMeasureHeader header){
685 		int nextIndex = header.getNumber();
686 		if(nextIndex < getSong().countMeasureHeaders()){
687 			return getSong().getMeasureHeader(nextIndex);
688 		}
689 		return null;
690 	}
691 
getMeasureHeaderAt(long start)692 	public TGMeasureHeader getMeasureHeaderAt(long start){
693 		Iterator it = getSong().getMeasureHeaders();
694 		while(it.hasNext()){
695 			TGMeasureHeader header = (TGMeasureHeader)it.next();
696 			long measureStart = header.getStart();
697 			long measureLength = header.getLength();
698 			if(start >= measureStart && start < measureStart + measureLength){
699 				return header;
700 			}
701 		}
702 		return null;
703 	}
704 
getMeasureHeader(int number)705 	public TGMeasureHeader getMeasureHeader(int number){
706 		for (int i = 0; i < getSong().countMeasureHeaders(); i++) {
707 			TGMeasureHeader header = getSong().getMeasureHeader(i);
708 			if(header.getNumber() == number){
709 				return header;
710 			}
711 		}
712 		return null;
713 	}
714 
715 	/**
716 	 * Retorna Todos los desde Start hasta el final del compas
717 	 */
getMeasureHeadersBeforeEnd(long fromStart)718 	public List getMeasureHeadersBeforeEnd(long fromStart) {
719 		List headers = new ArrayList();
720 		Iterator it = getSong().getMeasureHeaders();
721 		while(it.hasNext()){
722 			TGMeasureHeader header = (TGMeasureHeader)it.next();
723 			if (header.getStart() >= fromStart) {
724 				headers.add(header);
725 			}
726 		}
727 		return headers;
728 	}
729 
730 	/**
731 	 * Retorna Todos los desde Start hasta el final del compas
732 	 */
getMeasureHeadersAfter(int number)733 	public List getMeasureHeadersAfter(int number) {
734 		List headers = new ArrayList();
735 		Iterator it = getSong().getMeasureHeaders();
736 		while(it.hasNext()){
737 			TGMeasureHeader header = (TGMeasureHeader)it.next();
738 			if (header.getNumber() > number) {
739 				headers.add(header);
740 			}
741 		}
742 		return headers;
743 	}
744 
745 	/**
746 	 * Retorna Todos los desde Start hasta el final del compas
747 	 */
getMeasureHeadersBetween(long p1,long p2)748 	public List getMeasureHeadersBetween(long p1,long p2) {
749 		List headers = new ArrayList();
750 		Iterator it = getSong().getMeasureHeaders();
751 		while(it.hasNext()){
752 			TGMeasureHeader header = (TGMeasureHeader)it.next();
753 			if ((header.getStart() + header.getLength()) > p1  &&  header.getStart() < p2) {
754 				headers.add(header);
755 			}
756 		}
757 		return headers;
758 	}
759 
removeLastMeasure()760 	public void removeLastMeasure(){
761 		removeLastMeasureHeader();
762 	}
763 
removeMeasure(long start)764 	public void removeMeasure(long start){
765 		removeMeasureHeader(start);
766 	}
767 
removeMeasure(int number)768 	public void removeMeasure(int number){
769 		removeMeasureHeader(number);
770 	}
771 
772 	/**
773 	 * Agrega un Compas
774 	 */
addMeasureHeader(TGMeasureHeader measure)775 	public void addMeasureHeader(TGMeasureHeader measure){
776 		getSong().addMeasureHeader(measure);
777 	}
778 
779 	/**
780 	 * Agrega un Compas
781 	 */
addMeasureHeader(int index,TGMeasureHeader measure)782 	public void addMeasureHeader(int index,TGMeasureHeader measure){
783 		getSong().addMeasureHeader(index,measure);
784 	}
785 
removeMeasureHeaders(int n1,int n2)786 	public void removeMeasureHeaders(int n1,int n2){
787 		for(int i = n1; i <= n2; i ++){
788 			TGMeasureHeader measure = getMeasureHeader(n1);
789 			removeMeasureHeader(measure);
790 		}
791 		/*
792 		Iterator it = getMeasureHeadersBetween(p1,p2).iterator();
793 		while(it.hasNext()){
794 			TGMeasureHeader measure = (TGMeasureHeader)it.next();
795 			removeMeasureHeader(measure);
796 		} */
797 	}
798 
removeLastMeasureHeader()799 	public void removeLastMeasureHeader(){
800 		removeMeasureHeader(getLastMeasureHeader());
801 	}
802 
removeMeasureHeader(long start)803 	public void removeMeasureHeader(long start){
804 		removeMeasureHeader(getMeasureHeaderAt(start));
805 	}
806 
removeMeasureHeader(int number)807 	public void removeMeasureHeader(int number){
808 		removeMeasureHeader(getMeasureHeader(number));
809 	}
810 
removeMeasureHeader(TGMeasureHeader header)811 	public void removeMeasureHeader(TGMeasureHeader header){
812 		long start = header.getStart();
813 		long length = header.getLength();
814 
815 		Iterator it = getSong().getTracks();
816 		while(it.hasNext()){
817 			TGTrack track = (TGTrack)it.next();
818 			getTrackManager().removeMeasure(track,start);
819 		}
820 		moveMeasureHeaders(getMeasureHeadersBeforeEnd(start + 1),-length,-1,true);
821 		getSong().removeMeasureHeader(header.getNumber() - 1);
822 	}
823 
replaceMeasureHeader(TGMeasureHeader newMeasure)824 	public TGMeasureHeader replaceMeasureHeader(TGMeasureHeader newMeasure){
825 		TGMeasureHeader header = getMeasureHeaderAt(newMeasure.getStart());
826 		header.makeEqual(newMeasure.clone(getFactory()));
827 		return header;
828 	}
829 
moveMeasureHeaders(List headers,long theMove,int numberMove,boolean moveComponents)830 	public void moveMeasureHeaders(List headers,long theMove,int numberMove,boolean moveComponents) {
831 		if(moveComponents){
832 			Iterator it = headers.iterator();
833 			while(it.hasNext()){
834 				TGMeasureHeader header = (TGMeasureHeader) it.next();
835 				moveMeasureComponents(header,theMove);
836 			}
837 		}
838 		Iterator it = headers.iterator();
839 		while (it.hasNext()) {
840 			TGMeasureHeader header = (TGMeasureHeader) it.next();
841 			moveMeasureHeader(header,theMove,numberMove);
842 		}
843 	}
844 
845 	/**
846 	 * Mueve el compas
847 	 */
moveMeasureHeader(TGMeasureHeader header,long theMove,int numberMove)848 	public void moveMeasureHeader(TGMeasureHeader header,long theMove,int numberMove){
849 		header.setNumber(header.getNumber() + numberMove);
850 		header.setStart(header.getStart() + theMove);
851 	}
852 
853 	/**
854 	 * Mueve el compas
855 	 */
moveMeasureComponents(TGMeasureHeader header,long theMove)856 	public void moveMeasureComponents(TGMeasureHeader header,long theMove){
857 		Iterator it = getSong().getTracks();
858 		while(it.hasNext()){
859 			TGTrack track = (TGTrack)it.next();
860 			getTrackManager().moveMeasure(getTrackManager().getMeasure(track,header.getNumber()),theMove);
861 		}
862 	}
863 
864 	/**
865 	 * Retorna true si el start esta en el rango del compas
866 	 */
isAtPosition(TGMeasureHeader header,long start)867 	public boolean isAtPosition(TGMeasureHeader header,long start){
868 		return (start >= header.getStart() && start < header.getStart() + header.getLength());
869 	}
870 
updateMarker(int measure,String title,TGColor color)871 	public TGMarker updateMarker(int measure,String title,TGColor color){
872 		TGMeasureHeader header = getMeasureHeader(measure);
873 		if(header != null){
874 			if(!header.hasMarker()){
875 				header.setMarker(getFactory().newMarker());
876 			}
877 			header.getMarker().setMeasure(measure);
878 			header.getMarker().setTitle(title);
879 			header.getMarker().getColor().setR(color.getR());
880 			header.getMarker().getColor().setG(color.getG());
881 			header.getMarker().getColor().setB(color.getB());
882 			return header.getMarker();
883 		}
884 		return null;
885 	}
886 
updateMarker(TGMarker marker)887 	public TGMarker updateMarker(TGMarker marker){
888 		return updateMarker(marker.getMeasure(),marker.getTitle(),marker.getColor());
889 	}
890 
removeMarker(TGMarker marker)891 	public void removeMarker(TGMarker marker){
892 		if(marker != null){
893 			removeMarker(marker.getMeasure());
894 		}
895 	}
896 
removeMarker(int number)897 	public void removeMarker(int number){
898 		TGMeasureHeader header = getMeasureHeader(number);
899 		if(header != null && header.hasMarker()){
900 			header.setMarker(null);
901 		}
902 	}
903 
removeAllMarkers()904 	public void removeAllMarkers(){
905 		Iterator it = getSong().getMeasureHeaders();
906 		while(it.hasNext()){
907 			TGMeasureHeader header = (TGMeasureHeader)it.next();
908 			if(header.hasMarker()){
909 				header.setMarker(null);
910 			}
911 		}
912 	}
913 
getMarkers()914 	public List getMarkers(){
915 		List markers = new ArrayList();
916 		Iterator it = getSong().getMeasureHeaders();
917 		while(it.hasNext()){
918 			TGMeasureHeader header = (TGMeasureHeader)it.next();
919 			if(header.hasMarker()){
920 				markers.add(header.getMarker());
921 			}
922 		}
923 		return markers;
924 	}
925 
getMarker(int number)926 	public TGMarker getMarker(int number){
927 		TGMeasureHeader header = getMeasureHeader(number);
928 		if(header != null && header.hasMarker()){
929 			return header.getMarker();
930 		}
931 		return null;
932 	}
933 
getPreviousMarker(int from)934 	public TGMarker getPreviousMarker(int from){
935 		TGMeasureHeader previous = null;
936 		Iterator it = getSong().getMeasureHeaders();
937 		while(it.hasNext()){
938 			TGMeasureHeader header = (TGMeasureHeader)it.next();
939 			if(header.hasMarker() && header.getNumber() < from){
940 				if(previous == null || previous.getNumber() < header.getNumber()){
941 					previous = header;
942 				}
943 			}
944 		}
945 		return (previous != null)?previous.getMarker():null;
946 	}
947 
getNextMarker(int from)948 	public TGMarker getNextMarker(int from){
949 		TGMeasureHeader next = null;
950 		Iterator it = getSong().getMeasureHeaders();
951 		while(it.hasNext()){
952 			TGMeasureHeader header = (TGMeasureHeader)it.next();
953 			if(header.hasMarker() && header.getNumber() > from){
954 				if(next == null || next.getNumber() > header.getNumber()){
955 					next = header;
956 				}
957 			}
958 		}
959 		return (next != null)?next.getMarker():null;
960 	}
961 
getFirstMarker()962 	public TGMarker getFirstMarker(){
963 		TGMeasureHeader first = null;
964 		Iterator it = getSong().getMeasureHeaders();
965 		while(it.hasNext()){
966 			TGMeasureHeader header = (TGMeasureHeader)it.next();
967 			if(header.hasMarker()){
968 				if(first == null || header.getNumber() < first.getNumber()){
969 					first = header;
970 				}
971 			}
972 		}
973 		return (first != null)?first.getMarker():null;
974 	}
975 
getLastMarker()976 	public TGMarker getLastMarker(){
977 		TGMeasureHeader next = null;
978 		Iterator it = getSong().getMeasureHeaders();
979 		while(it.hasNext()){
980 			TGMeasureHeader header = (TGMeasureHeader)it.next();
981 			if(header.hasMarker()){
982 				if(next == null || header.getNumber() > next.getNumber()){
983 					next = header;
984 				}
985 			}
986 		}
987 		return (next != null)?next.getMarker():null;
988 	}
989 
autoCompleteSilences()990 	public void autoCompleteSilences(){
991 		Iterator it = getSong().getTracks();
992 		while(it.hasNext()){
993 			TGTrack track = (TGTrack)it.next();
994 			getTrackManager().autoCompleteSilences(track);
995 		}
996 	}
997 
orderBeats()998 	public void orderBeats(){
999 		Iterator it = getSong().getTracks();
1000 		while(it.hasNext()){
1001 			TGTrack track = (TGTrack)it.next();
1002 			getTrackManager().orderBeats(track);
1003 		}
1004 	}
1005 
createDefaultInstrumentStrings()1006 	public List createDefaultInstrumentStrings(){
1007 		List strings = new ArrayList();
1008 		strings.add(newString(getFactory(),1, 64));
1009 		strings.add(newString(getFactory(),2, 59));
1010 		strings.add(newString(getFactory(),3, 55));
1011 		strings.add(newString(getFactory(),4, 50));
1012 		strings.add(newString(getFactory(),5, 45));
1013 		strings.add(newString(getFactory(),6, 40));
1014 		return strings;
1015 	}
1016 
createPercussionStrings(TGFactory factory,int stringCount)1017 	public static List createPercussionStrings(TGFactory factory,int stringCount){
1018 		List strings = new ArrayList();
1019 		for(int i = 1;i <= stringCount; i++){
1020 			strings.add(newString(factory,i, 0));
1021 		}
1022 		return strings;
1023 	}
1024 
newString(TGFactory factory,int number,int value)1025 	public static TGString newString(TGFactory factory,int number,int value){
1026 		TGString string = factory.newString();
1027 		string.setNumber(number);
1028 		string.setValue(value);
1029 		return string;
1030 	}
1031 
getDivisionLength(TGMeasureHeader header)1032 	public static long getDivisionLength(TGMeasureHeader header){
1033 		long defaultLenght = TGDuration.QUARTER_TIME;
1034 		int denominator = header.getTimeSignature().getDenominator().getValue();
1035 		switch(denominator){
1036 			case TGDuration.EIGHTH:
1037 				if(header.getTimeSignature().getNumerator() % 3 == 0){
1038 					defaultLenght += TGDuration.QUARTER_TIME / 2;
1039 				}
1040 				break;
1041 		}
1042 		return defaultLenght;
1043 	}
1044 }
1045