/**
 * Map Generator Groovy weather sample
 */
package weather.data;

import groovy.transform.ToString;

import idea.graphics.shapes.complex.meteo.WindBarb;
import idea.graphics.shapes.complex.meteo.WindBarb.SkyCoverage;

/**
 * Weather info 
 * 
 * @author Lumir Vanek, vanek@idea-envi.cz
 *
 */
@ToString
class Weather 
{
	/**
	 * Wind speed in Knots
	 */
	final int windSpeed;
	
	/**
	 * Direction (in degrees) that the wind is blowing from. This means that 45 degrees is Northeast wind.
	 * Null means Variable wind direction
	 */
	final Integer windDirection;
	
	/**
	 * Air barometric pressure referred to mean sea level, (QNH)
	 */
	final int airPressure;
	
	/**
	 * Sky coverage
	 */
	final WindBarb.SkyCoverage skyCoverage;
	
	/**
	 * Original undecoded METAR
	 */
	final String metarOrigin;
	
	/**
	 * Constructor. Decode weather from METAR. See:
	 * http://en.wikipedia.org/wiki/METAR
	 * 
	 * @param icaoCode Airport ICAO code
	 * @param metar METAR text
	 */
	public Weather(String icaoCode, String metar)
	{
		String [] pieces = metar.split("\\s");
		
		// Check, if decoded METAR is for our airport
		assert pieces[2].equals(icaoCode);
		
		int startPos = 4;
		
		/**
		 * Wind
		 */
		String direction = null;
		String speed = null;
		
		def patternWind = ~"^(VRB|\\d{3})(\\d{2})KT\$";
		def patternWindGust = ~"^\\d{5}G\\d{2}KT\$";
		pieces[startPos..-1].find
		{
			if((it =~ patternWind) || (it =~ patternWindGust))
			{
				direction = it[0..2];
				speed = it[3..4];
				startPos++;
				true;
			}
			false;
		}
		
		def patternWindVariable = ~"^\\d{3}V\\d{3}\$";
		pieces[startPos..-1].find
		{
			if(it =~ patternWindVariable)
			{
				startPos++;
				println it;
				true;
			}
			false;
		}

		/*
		 * Sky
		 */
		WindBarb.SkyCoverage skyCoverage = SkyCoverage.NONE;
		def patternSky = ~"^(SKC|FEW|SCT|BKN|OVC)(\\d{3})?(CU|CB|TCU|CI)?\$";
		pieces[startPos..-1].each
		{
			String it ->
			if(it =~ patternSky)
			{
				skyCoverage = SkyCoverage.decode(it[0..3]);
				startPos++;
			}
			else if(it.equals('CAVOK'))
			{
				skyCoverage = SkyCoverage.CLEAR;
				startPos++;
			}
		}
				
	   /*
		* Find QNH
		*/
	   String qnh = null;
	   def patternPressure = ~"^Q\\d{4}\$";
	   pieces[startPos..-1].find
	   {
		   String it ->
		   if(it =~ patternPressure)
		   {
			   qnh = it[1..4];
			   startPos++;
			   true;
		   }
		   false;
	   }
	   
	   println pieces[2] + ' - ' + direction + ' degrees ' + speed + ' knots, ' + qnh + ' hPa, ' + skyCoverage;

	   this.windDirection = direction.equals('VRB') ? null : Integer.parseInt(direction);
	   this.windSpeed = Integer.parseInt(speed);
	   this.airPressure = Integer.parseInt(qnh);
	   this.skyCoverage = skyCoverage;
	   this.metarOrigin = metar;
	}
}