
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Iterator;
/* 'JSON-Simple' library */
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import vo.parameter.*;

public class JsonEncoder
{
   static final Logger LOGGER = Logger.getLogger(JsonEncoder.class.getName());

   private JSONObject obj;

   public JsonEncoder() { this.obj = new JSONObject(); this.obj.put("service","SUBIMG"); }

   public String toString() { return this.obj.toString(); }


   public void add(String pathname, int hdunum)
   {
      this.obj.put("img_pathname", pathname);
      this.obj.put("img_hdunum",   hdunum);
   }


   // NOTE: implementation of NULL: do not put into json

   public void add(Pos pos)
   {
      LOGGER.fine("trace");

      if(pos != null)
      {
         JSONObject j = new JSONObject();
         j.put("system", pos.system.toString());

         if(pos.circle  != null) j.put("circle",  objJCircle(pos.circle));
         if(pos.range   != null) j.put("range",   objJRange(pos.range));
         if(pos.polygon != null) j.put("polygon", objJPolygon(pos.polygon));

         this.obj.put("pos", j);
      }
   }


   public void add(Band band)
   {
      if(band != null)
      {
         JSONObject j = new JSONObject();
         j.put("system", band.system.toString());

         JSONArray arr = new JSONArray();
         arr.add(band.min);
         arr.add(band.max);
         j.put("interval",arr);

         this.obj.put("band", j);
      }
   }


   public void add(Time time)
   {
      if(time != null)
      {
         JSONObject j = new JSONObject();
         j.put("system", time.system.toString());

         JSONArray arr = new JSONArray();
         arr.add(time.min);
         arr.add(time.max);
         j.put("interval",arr);

         this.obj.put("time", j);
      }
   }


   public void add(Pol pol)
   {
      if(pol != null)
      {
         JSONArray arr = new JSONArray();
         for(String val : pol.states) arr.add(val);
         this.obj.put("pol",arr);
      }
   }

   public void add(Pixeli[] pixiArr)
	{
		if(pixiArr != null)
		{
			JSONArray jarr = new JSONArray();
			for(Pixeli elem : pixiArr)
			{
				JSONObject j = new JSONObject();
				j.put("pix1", elem.pix1);
				j.put("pix2", elem.pix2);
				j.put("type", elem.type);
				jarr.add(j);
			}
			this.obj.put("pixel_i", jarr);
		}
	}



	public void add(FitsCard[] extraCards)
	{
		if((extraCards != null) && (extraCards.length > 0)) 
		{
			obj.put("extra_cards", extraCardsToJson(extraCards));
		}
	}


	public void add(boolean countNullValues)
	{
		obj.put("count_null_values", countNullValues);
	}



	private JSONArray extraCardsToJson(FitsCard[] extraCards)
	{
		JSONArray jcards = new JSONArray();
		for(FitsCard card : extraCards)
		{
			JSONObject j = new JSONObject();
			j.put("key",     card.key);
			j.put("value",   card.value);
			j.put("comment", card.comment);
			jcards.add(j);
		}
		return jcards;
	}


	private JSONObject objJCircle(Circle circle)
	{
		JSONObject obj = new JSONObject();
		obj.put("lon", circle.lon);
		obj.put("lat", circle.lat);
		obj.put("radius", circle.radius);
		return obj;
	}


	private JSONObject objJRange(Range range)
	{
		JSONObject obj = new JSONObject();
		obj.put("lon1", range.lon1);
		obj.put("lon2", range.lon2);
		obj.put("lat1", range.lat1);
		obj.put("lat2", range.lat2);
		return obj;
	}

	private JSONObject objJPolygon(Polygon poly)
	{
		JSONObject obj = new JSONObject();
		obj.put("lon", genPolyLonJsonArr(poly));
		obj.put("lat", genPolyLatJsonArr(poly));
		return obj;
	}


	private JSONArray genPolyLonJsonArr(Polygon polygon)
	{
		JSONArray jarr = new JSONArray();
		for(double dbl : polygon.lon) jarr.add(dbl);
		return jarr;
	}


	private JSONArray genPolyLatJsonArr(Polygon polygon)
	{
		JSONArray jarr = new JSONArray();
		for(double dbl : polygon.lat) jarr.add(dbl);
		return jarr;
	}

}

