import java.io.File;
import java.util.*;
import javax.sound.sampled.*;

import com.dukascopy.api.*;



public class Alarm implements IStrategy {
	//containers
	private List<AlarmLine> lineList;
	private List<IChartObject> chartObjectList;
	private Iterator<IChartObject> chartObjectIterator;
	private Iterator<AlarmLine> alarmLineIterator;
	
	@Configurable("Instrument:")
	public Instrument instrument = Instrument.EURUSD;
	@Configurable("Number of loops:")
	public int loops = 6;
	@Configurable("Wave File:")
	public File alarmFile = new File("C:\\Windows\\Media\\Chimes.wav");
	@Configurable("Alarm beeps on tick or bar close")
	public boolean barClose = false;
	private IChart chart;
	private IConsole console;
	private IHistory history;
	private IContext context;
	private ITick formerTick;
	
	private int objectCount = 0;
	private int startObjectCount = 0;
	
	//Constructor
	public void Alarm() {
		lineList = new ArrayList<AlarmLine>();
		chartObjectList = new ArrayList<IChartObject>();
		alarmLineIterator = null;
		chartObjectIterator = null;
		
	}

	@Override
	public void onAccount(IAccount account) throws JFException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onBar(Instrument instrument, Period period, IBar askbar, IBar bidbar)
			throws JFException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMessage(IMessage message) throws JFException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onStart(IContext context) throws JFException {
		// TODO Auto-generated method stub
		this.context = context;
		this.chart = context.getChart(this.instrument);
		this.console = context.getConsole();
		this.history = context.getHistory();
		this.formerTick = history.getLastTick(this.instrument);
		
		if(this.chart == null) {
			console.getErr().println("No chart opened for " + this.instrument);
			context.stop(); //stop the strategy
		}
		
		if(this.chart.getAll().size()>0) {
			this.startObjectCount = chart.getAll().size();
			this.objectCount = this.startObjectCount;
			
			//fill list
			this.chartObjectList.addAll(chart.getAll());
			
		}
		
		ITick tick = history.getLastTick(this.instrument);
		
		if(this.chartObjectList.isEmpty()) {
			console.getWarn().println("Add objects on chart!");
		}
		
		
	}

	@Override
	public void onStop() throws JFException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onTick(Instrument instrument, ITick tick) throws JFException {
		// get number of objects and if it's changed clear both lists
		objectCount = chart.getAll().size();
		
		if(objectCount != startObjectCount) {
			if(lineList.size() != 0 && chartObjectList.size() != 0) {
				lineList.clear();
				chartObjectList.clear();
			}
			
			if(chart.getAll().size()>0) {
				startObjectCount = chart.getAll().size();
				objectCount = startObjectCount;
				
				//fill list again
				chartObjectList.addAll(chart.getAll());
				
			}
			for(chartObjectIterator = chartObjectList.iterator(); chartObjectIterator.hasNext();) {
				//comparing all objects
				if(chartObjectList.iterator() == IHorizontalLine) {
					lineList.add(chartObjectList.iterator());
				}
			}
			
			startObjectCount = objectCount;
		}
	}
	
	private void PlaySound(File waveFile) throws JFException{
		try {
			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(waveFile);
			AudioFormat af = audioInputStream.getFormat();
	        int nSize = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
	        byte[] audio = new byte[nSize];
	        DataLine.Info info = new DataLine.Info(Clip.class, af, nSize);
	        audioInputStream.read(audio, 0, nSize);
	        Clip clip = (Clip) AudioSystem.getLine(info);
	        clip.open(af, audio, 0, nSize);
	        for(int i=0; i<this.loops; i++){
	        	clip.start();
	        }
		}
		catch (Exception e) {
        e.printStackTrace();
        print("Missing file or error on play: " + e.getMessage());
        //throw new JFException(e);
        }
	}
    
    private void print(Object o){
        this.context.getConsole().getOut().println(o);
    }


}


