/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.utils.entitymock;

import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class Iterators {
	
	public static class IntegerIterator extends Iterators implements Iterator<Integer> {
	    private final int until;
	    private final int step;
	    private int position;

	    public IntegerIterator(int from, int until) {
	    	this(from, until, 1);
	    }

	    public IntegerIterator(int from, int until, int step) {
	    	if	(until < from) {
	    		int swap = until;
	    		until = from;
	    		from = swap;
	    	}
	    	if	(step < 1) {
	    		step = 1;
	    	}
	        this.until = until;
	        this.step = step;
	        position = from-step;
	    }

	    @Override
	    public boolean hasNext() {
	        return position < until;
	    }

	    @Override
	    public Integer next() {
	    	if	(!hasNext()) {
	            throw new NoSuchElementException();
	        }
	        position += step;
	        return position;
	    }
	}
	
	public static class DateIterator extends Iterators implements Iterator<Date> {
	    private final Calendar until;
	    private final int stepCount;
	    private final int stepType;
	    private Calendar position;

	    private static Date toDate(String text) {
	    	text = text.toLowerCase();
	    	Calendar date = Calendar.getInstance(); 
	    	if	(text.equals("yesterday")) {
	    		date.add(Calendar.DAY_OF_YEAR, -1);
	    	}
	    	else if	(text.equals("today")) {
	    	}
	    	else if	(text.equals("tomorrow")) {
	    		date.add(Calendar.DAY_OF_YEAR, 1);
	    	}
	    	else {
	    		String[] tokens = text.split("-");
		    	try {
		    		if	(tokens.length == 3) {
		    			date.set(
	    					Integer.parseInt(tokens[0]),
	    					Integer.parseInt(tokens[1])-1,
	    					Integer.parseInt(tokens[2]));
		    		}
		    	}
		    	catch (Exception e) {
		    		System.err.println(e.getLocalizedMessage());
		    	}
	    	}
	    	return date.getTime();
	    }

	    private static int toStepType(String text) {
	    	switch (text.toLowerCase().charAt(0)) {
	    		case 'y': return Calendar.YEAR;
	    		case 'm': return Calendar.MONTH;
	    		case 'w': return Calendar.WEEK_OF_YEAR;
	    	}
	    	return Calendar.DAY_OF_YEAR;
	    }
	    
	    public DateIterator(String from, String until) {
	    	this(toDate(from), toDate(until), 1, Calendar.DAY_OF_YEAR);
	    }

	    public DateIterator(Date from, Date until) {
	    	this(from, until, 1, Calendar.DAY_OF_YEAR);
	    }

	    public DateIterator(String from, String until, int stepCount, String stepType) {
	    	this(toDate(from), toDate(until), 1, toStepType(stepType));
	    }

	    public DateIterator(Date from, Date until, int stepCount, int stepType) {
	    	if	(until.before(from)) {
	    		Date swap = until;
	    		until = from;
	    		from = swap;
	    	}
	    	if	(stepCount < 1) {
	    		stepCount = 1;
	    	}
	        this.until = Calendar.getInstance();
	        this.until.setTime(until);
	        this.stepCount = stepCount;
	        this.stepType = stepType;
	        position = Calendar.getInstance();
	        position.setTime(from);
	        position.add(stepType, -stepCount);
	    }

	    @Override
	    public boolean hasNext() {
	        return position.before(until);
	    }

	    @Override
	    public Date next() {
	    	if	(!hasNext()) {
	            throw new NoSuchElementException();
	        }
	        position.add(stepType, stepCount);
	        return position.getTime();
	    }
	}
}
