package org.uoc.pac3.DroidEye;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Scalar;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.util.Log;


/**
 * @author Jordi Anducas Aregall
 * 
 *Aquesta classe es derivada de coin, això és així perque
 *volem emmagatzemar una llista de coins teòriques
 *aquesta llista de coins teòriques serveixen per trobar 
 *el nom de les coins que s'ha trobat
 *
 */

public class CoinsTeoric {

	//Llista de monedes teoriques
	public List<Coin> ListCoins = new ArrayList<Coin>();


	CoinsTeoric(Context context)
	{
		CarregarDades(context);

	}



	/**
	 * @param mCoin
	 * @return
	 * Ara tenim que trobar quina moneda és cada una.
	 * Això ho realitzarem comparant els diferents tipus de monedes 
	 * que hi han configurades com a teoriques.
	 * El que es fa primer es comparar el color per saber si estan en el rang
	 * i un cop passat aquest filtre es comprova quin és el millor
	 * radi que hi ha entre totes les monedes tèoriques i les que 
	 * es volen comparar
	 */
	public String CompareCoins(Coin mCoin)
	{
		double offsetColour=500;

		Coin mCoinResult = new Coin("",99999999,new Scalar(0,0,0,0));

		for (int i = 0; i < ListCoins.size(); i++) {

			//Entre coins teorics i reals
			int difpix1=Math.abs(mCoin.getRadius()-ListCoins.get(i).getRadius());
			double difcolour1=ColourDistance(mCoin.getColor(),ListCoins.get(i).getColor());

			//Entre coins reals i millor trobat
			int difpix2=Math.abs(mCoin.getRadius()-mCoinResult.getRadius());
			double difcolour2=ColourDistance(mCoin.getColor(),mCoinResult.getColor());


			double offsetColourP=difcolour2+offsetColour;
			double offsetColourM=difcolour2-offsetColour;

			//Comprobem que el color sigui compatible
			if((difcolour1<offsetColourP)&&(difcolour1>offsetColourM))
			{
				//Ara mirem el millor radi
				if(difpix1<difpix2)
				{
					mCoinResult=ListCoins.get(i);
				}
			}
		}



		return mCoinResult.GetName();

	}


	double ColourDistance(Scalar colour1, Scalar colour2)
	{
		long rmean = ( (long)colour1.val[0] + (long)colour2.val[0] ) / 2;
		long r = (long)colour1.val[0] - (long)colour2.val[0];
		long g = (long)colour1.val[1] - (long)colour2.val[1];
		long b = (long)colour1.val[2] - (long)colour2.val[2];
		return Math.sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
	}



	public void CarregarDades(Context context)
	{
		Coin mCoin;
		String mName;
		int mRadius;//pixels
		Scalar mColor;
		
		//get arbitary xml data via parser
		Resources res = context.getResources(); 
		XmlResourceParser xrp = res.getXml(R.xml.coins);

		try {
			//from http://d.android.com/reference/org/xmlpull/v1/XmlPullParser.html
			int eventType = xrp.getEventType();

			while (eventType != XmlPullParser.END_DOCUMENT) {
				if(eventType == XmlPullParser.START_TAG) {
					if(xrp.getName().equals("coin")) {
						
							
							mName=xrp.getAttributeValue(0);
							mRadius=Integer.parseInt(xrp.getAttributeValue(1));
							mColor= new Scalar(Integer.parseInt(xrp.getAttributeValue(2)),
									Integer.parseInt(xrp.getAttributeValue(3)),
									Integer.parseInt(xrp.getAttributeValue(4)),255);
							mCoin= new Coin(mName,mRadius,mColor);
							ListCoins.add(mCoin);
					}
				}
				eventType = xrp.next();
			}

		}catch(IOException ioe) {
			Log.e("Exception", ioe.getStackTrace().toString());
		}catch(XmlPullParserException xppe) {
			Log.e("Exception", xppe.getStackTrace().toString());
		}finally{
			xrp.close();
		} 


	}

	
	private void CarregarManual()
	{
		Coin mCoin;
		String mName;
		int mRadius;//pixels
		Scalar mColor;


		//En aquest punt introduim les monedes toriques que podem tenir
		//-----------------------------------------------------------------
		//1 centim
		mName="1c";
		mRadius=192;
		mColor= new Scalar(100,50,15,255);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//2 centim
		mName="2c";
		mRadius=230;
		mColor= new Scalar(100,50,15,255);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//5 centim
		mName="5c";
		mRadius=254;
		mColor= new Scalar(100,50,15,255);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//10 centim
		mName="10c";
		mRadius=245;
		mColor= new Scalar(120,100,16,0);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//20 centim
		mName="20c";
		mRadius=270;
		mColor= new Scalar(120,100,30,0);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//50 centim
		mName="50c";
		mRadius=287;
		mColor= new Scalar(120,100,30,0);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//1 euro
		mName="1e";
		mRadius=282;
		mColor= new Scalar(85,60,30,0);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
		//2 euros
		mName="2e";
		mRadius=302;
		mColor= new Scalar(100,80,30,0);
		mCoin= new Coin(mName,mRadius,mColor);
		ListCoins.add(mCoin);
		//-----------------------------------------------------------------
	}
}
