
import jm.JMC;
import jm.music.data.*;
import jm.util.*;
import jm.music.tools.Mod;

public class GridMusic7 implements JMC {
    private Phrase hats, snare, kick;
    private Part drums;
    private int repeats;
    
    public GridMusic7() {
        hats = new Phrase(0.0);
        snare = new Phrase(0.0);
        kick = new Phrase(0.0);
        drums = new Part("Drums", 26, 9);
        drums.setTempo(60);
        drums.addPhrase(hats);
        drums.addPhrase(snare);
        drums.addPhrase(kick);
    }
    
    /**
    * Create the initial state of the music by filling arrays with notes and rests.
    */
    public void compose() {
         int[] hatsHits = 
            {REST, REST, FS2, REST, REST, REST, FS2, REST, REST, REST, FS2, REST, REST, REST, FS2, REST,};
        hats.addNoteList(hatsHits, SIXTEENTH_NOTE, 127);
        int[] snareHits = 
            {REST, REST, REST, REST, D2, REST, REST, REST, REST, REST, REST, REST, D2, REST, D2, REST};
        snare.addNoteList(snareHits, SIXTEENTH_NOTE, 127);
        int[] kickHits = 
            {C2, REST, REST, REST, REST, REST, REST, C2, C2, REST, REST, REST, REST, REST, REST, REST};
        kick.addNoteList(kickHits, SIXTEENTH_NOTE, 127);
    }
    
    /**
    * Specify the pitch (including as a REST) of a note in the hats array.
    * @param arrayIndex The note to be changed.
    * @param pitch The value to change it's pitch to.
    */
    public void setHatsPitch(int arrayIndex, int pitch) {
        hats.getNote(arrayIndex).setPitch(pitch);
    }
    
    /**
    * Specify the pitch (including as a REST) of a note in the snare array.
    * @param arrayIndex The note to be changed.
    * @param pitch The value to change it's pitch to.
    */
    public void setSnarePitch(int arrayIndex, int pitch) {
        snare.getNote(arrayIndex).setPitch(pitch);
    }
    
    /**
    * Specify the pitch (including as a REST) of a note in the kick array.
    * @param arrayIndex The note to be changed.
    * @param pitch The value to change it's pitch to.
    */
    public void setKickPitch(int arrayIndex, int pitch) {
        kick.getNote(arrayIndex).setPitch(pitch);
    }
    
    /**
    * Pass back weather or not the specified hat note is a rest or not.
    * @return boolean True if it is a pitched note, false if it is a rest.
    */
    public boolean getHatsState(int arrayIndex) {
        return (!hats.getNote(arrayIndex).isRest());
    }
    
    /**
    * Pass back weather or not the specified snare note is a rest or not.
    * @return boolean True if it is a pitched note, false if it is a rest.
    */
    public boolean getSnareState(int arrayIndex) {
        return (!snare.getNote(arrayIndex).isRest());
    }

    /**
    * Pass back weather or not the specified kick note is a rest or not.
    * @return boolean True if it is a pitched note, false if it is a rest.
    */
    public boolean getKickState(int arrayIndex) {
        return (!kick.getNote(arrayIndex).isRest());
    }

    public void repeatMusic(int times) {
        this.repeats = times;
    }
    
    public void setTempo(double tempo) {
        drums.setTempo(tempo);
    }
    
    /**
    * Save the music as a standard MIDI file.
    * @param fileName The name of the MIDI file, usually ending in .mid
    */
    public void saveFile(String fileName) {
        Part temp = drums.copy();
        Mod.repeat(temp, this.repeats);
        Write.midi(temp, fileName);
    }
    
    /**
    * Playback the music using JavaSound internal synth sounds.
    */ 
    public void play() {
        Part temp = drums.copy();
        Mod.repeat(temp, this.repeats);
        Play.midi(temp, false);
    }

  }
