package com.view;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import net.HttpActionManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.ZoomControls;
import basicClass.Event;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class SearchEvents extends MapActivity implements OnGestureListener,OnTouchListener{
	PopupWindow pw;
	ViewGroup vg;
	MapView mv;
	MapController mController;
	LocationManager lm;
	Location loc;
	String lProvider="";
	GeoPoint current_gp;
	int zoom=15;
	ZoomControls mZoom;
	GestureDetector detector;
	List<Event> events=null;
	
	
	static final int REQUEST_LIST=0;
	static final int REQUEST_DETAIL=1;
	
	Point m_curLocation;
	LocationProvider m_locProvider;
	LocationManager m_locMgr;
	
	HttpActionManager mManager = new HttpActionManager();
	
	public void onCreate(Bundle b)
	{
		super.onCreate(b);
		setContentView(R.layout.searchevents);
		
		
		//vg=(ViewGroup)findViewById(R.id.vg);
		//pw=new PopupWindow();
		//mv=new MapView(this,"");
		//mv.setClickable(true);
		//mv.setEnabled(true);
		//vg.addView(mv, 0);
		detector=new GestureDetector(this);

		mv=(MapView)findViewById(R.id.map_in_search);
		mController=mv.getController();
		mController.setZoom(zoom);
		lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
		
		getLocationProvider();
		buildGPS();
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, listen_loc);
		loc=(lProvider==null)?lm.getLastKnownLocation(LocationManager.GPS_PROVIDER):lm.getLastKnownLocation(lProvider);
		//loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		double gLat=loc.getLatitude()*1E6;
		double gLon=loc.getLongitude()*1E6;
		current_gp=new GeoPoint((int)gLat,(int)gLon);
		mController.animateTo(current_gp);
		//refreshMap();
		//((TextView)findViewById(R.id.addr_in_search)).setText("Lat "+loc.getLatitude()+"  Long "+loc.getLongitude());
		Point p = new Point();
		p=mv.getProjection().toPixels(current_gp, p);
		//((TextView)findViewById(R.id.addr_in_search)).setText(p.x+"  "+p.y);
		
		LinearLayout linear_zoom=(LinearLayout)findViewById(R.id.zoomview);
		mZoom=(ZoomControls)mv.getZoomControls();
		linear_zoom.addView(mZoom);
		mv.setOnTouchListener(this);
		mv.requestFocus();
		LocationOverlay ol=new LocationOverlay(true,current_gp);
		List<Overlay> list=mv.getOverlays();
		list.add(ol);
		
		GeoPoint[] gp2=this.getGPSSpan();
		Log.e("Location",current_gp.getLatitudeE6()+" "+current_gp.getLongitudeE6()+" "+"++++++++++++++");

		this.setEvents(mManager.searchEventByLocationGPS(90,0 , 
				120, 100));
		Log.e("Received List",events.size()+"***********************");

	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	LocationListener listen_loc=new LocationListener()
	{
		public void onLocationChanged(Location loc)
		{
			if(loc!=null)
				Log.i("Super Map", "Location Changed: Lat: "+loc.getLatitude()+" Lng: "+loc.getLongitude());
			
			current_gp = new GeoPoint((int) (loc.getLatitude() * 1E6), (int) (loc.getLongitude() * 1E6));
			mController.animateTo(current_gp);
			mController.setZoom(zoom);
			mv.invalidate(); 
		}
		public void onProviderDisabled(String pro)
		{
			//when provider is disabled
		}
		public void onProviderEnabled(String pro)
		{
			//when provider is enabled
		}
		public void onStatusChanged(String pro,int status,Bundle extra)
		{
			
		}
	};
	
	private GeoPoint getGeoByLocation(Location l)
	{
		GeoPoint gp=null;
		try{
			if(l!=null)
			{
				double gLat=l.getLatitude()*1E6;
				double gLon=l.getLongitude()*1E6;
				gp=new GeoPoint((int)gLat,(int)gLon);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return gp;
	}
	
	public void getLocationProvider()
	{
		Criteria mc=new Criteria();
		mc.setAccuracy(Criteria.ACCURACY_FINE);
		mc.setAltitudeRequired(false);
		mc.setBearingRequired(false);
		mc.setCostAllowed(true);
		mc.setPowerRequirement(Criteria.POWER_LOW);
		
		lProvider=lm.getBestProvider(mc, true);
		
		loc=lm.getLastKnownLocation(lProvider);
	}
	
	public void refreshMap()
	{
		mv.displayZoomControls(true);
		MapController tmpMC=mv.getController();
		tmpMC.animateTo(current_gp);
		tmpMC.setZoom(zoom);
		mv.setSatellite(false);
		//((TextView)findViewById(R.id.addr_in_search)).setText(this.getAddressByGeoPoint(current_gp));
	}
	
	

	protected void onActivityResult(int request,int result,Intent data)
	{
		if(request==REQUEST_LIST)
			if(result==RESULT_OK)
			{
				//Bundle b=data.getExtras();
				//String centricId=b.getString("CentricEvent");
				//set centricId as the beginning on the list
			}
	}
	
	private void buildGPS()
	{
		List<LocationProvider> providerList=null;
		Criteria c=new Criteria();
		
		c.setAccuracy(50);
		c.setAltitudeRequired(false);
		c.setCostAllowed(true);
		c.setSpeedRequired(false);
		
		lm=(LocationManager)getSystemService(LOCATION_SERVICE);
		m_locProvider=lm.getProvider(lm.getBestProvider(c, true));
		lProvider=m_locProvider.getName();
		if(m_locProvider!=null) return;
		
		List<String> m_proNameList=m_locMgr.getAllProviders();
		for(int i=0;i<m_proNameList.size();i++)
			providerList.add(m_locMgr.getProvider(m_proNameList.get(i)));
		
		if(providerList.size()>0)
		{	m_locProvider=providerList.get(0);
		lProvider=m_locProvider.getName();
		loc=lm.getLastKnownLocation(lProvider);
		}
		
		//loc=lm.getLastKnownLocation(lProvider);
		
		
		
	}
	OnClickListener click_search=new OnClickListener()
	{
		public void onClick(View view)
		{
			SearchWindow.requestUpdate(SearchEvents.this);
		}
	};
	
	OnClickListener click_zoomUp=new OnClickListener()
	{
		public void onClick(View view)
		{
			zoom++;
			if(zoom>mv.getMaxZoomLevel())
				zoom=mv.getMaxZoomLevel();
			mController.setZoom(zoom);
			refreshMap();
		}
	};
	
	OnClickListener click_zoomDown=new OnClickListener()
	{
		public void onClick(View v)
		{
			zoom--;
			if(zoom<1) zoom=1;
			mController.setZoom(zoom);
			refreshMap();
		}
	};

	public boolean onTouchEvent(MotionEvent event)
	{
		detector.onTouchEvent(event);
		return true;
	}
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		// TODO Auto-generated method stub
		return false;
	}

	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		GeoPoint orig_gp=pixelToPoint((int)e1.getX(),(int)e1.getY());
		GeoPoint tmp_gp=pixelToPoint((int)e2.getX(),(int)e2.getY());
		if(tmp_gp!=null)
		{
			//current_gp=tmp_gp;
			//System.out.println(current_gp.getLatitudeE6());
			//System.out.println(current_gp.getLongitudeE6());
			
			int newLat1E6=current_gp.getLatitudeE6()-(tmp_gp.getLatitudeE6()-orig_gp.getLatitudeE6());
			int newLon1E6=current_gp.getLongitudeE6()-(tmp_gp.getLongitudeE6()-orig_gp.getLongitudeE6());
			current_gp=new GeoPoint(newLat1E6,newLon1E6);
			mController.animateTo(current_gp);
			//((TextView)findViewById(R.id.addr_in_search)).setText("Lat "+current_gp.getLatitudeE6()/(double)1E6+"  Long "+current_gp.getLongitudeE6()/(double)1E6);
			refreshMap();
		}
		return true;
	}

	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
	/*
		GeoPoint tmp_gp=pixelToPoint((int)e.getX(),(int)e.getY());
		if(tmp_gp!=null)
		{
			current_gp=tmp_gp;
			System.out.println(current_gp.getLatitudeE6());
			System.out.println(current_gp.getLongitudeE6());
			mController.animateTo(current_gp);
			//((TextView)findViewById(R.id.addr_in_search)).setText("Lat "+current_gp.getLatitudeE6()/(double)1E6+"  Long "+current_gp.getLongitudeE6()/(double)1E6);
			refreshMap();
		}*/
		return false;
	}
	
	public GeoPoint pixelToPoint(int x,int y)
	{
			double latPerHPix=mv.getLatitudeSpan()/(double)mv.getHeight();
			double lonPerWPix=mv.getLongitudeSpan()/(double)mv.getWidth();
			
			int centet_lon=current_gp.getLongitudeE6();
			int centet_lat=current_gp.getLatitudeE6();
			
			int gap_lon=(int)(x*lonPerWPix);
			int gap_lat=(int)(y*latPerHPix);
			Point p=new Point(320,280);
			GeoPoint top_left=mv.getProjection().fromPixels(0, 0);
			return new GeoPoint(top_left.getLatitudeE6()-gap_lat,top_left.getLongitudeE6()+gap_lon);
		
	}

	
	
	public String getAddressByGeoPoint(GeoPoint gp)
	{
		String strReturn="";
		try
		{
			if(gp!=null)
			{
				Geocoder gc=new Geocoder(SearchEvents.this,Locale.getDefault());
				double glat=(int)gp.getLatitudeE6()/1E6;
				double glon=(int)gp.getLongitudeE6()/1E6;
				
				List<Address> lstAddr=gc.getFromLocation(glat, glon, 1);
				StringBuilder builder=new StringBuilder();
				
				if(lstAddr.size()>0)
				{
					Address adsLoc=lstAddr.get(0);
					
					for(int i=0;i<adsLoc.getMaxAddressLineIndex();i++)
						builder.append(adsLoc.getAddressLine(i)).append("\n");
					builder.append(adsLoc.getLocality()).append("\n");
					builder.append(adsLoc.getPostalCode()).append("\n");
					builder.append(adsLoc.getCountryName());
				}
				strReturn=builder.toString();
			}
		}
		catch(Exception e){e.printStackTrace();}
		
		return strReturn;
	}
	
	class LocationOverlay extends com.google.android.maps.Overlay
	{
		boolean isHere;
		GeoPoint gp;
		public LocationOverlay(boolean isHere,GeoPoint gp)
		{
			this.isHere=isHere;
			this.gp=gp;
		}
		public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when)
		{
			super.draw(canvas, mapView, shadow);
			Paint paint=new Paint();
			Point coor=new Point();
			mv.getProjection().toPixels(gp, coor);
			paint.setStrokeWidth(1);
			paint.setARGB(255, 255, 255, 255);
			paint.setStyle(Paint.Style.STROKE);
			Bitmap bmp0=BitmapFactory.decodeResource(getResources(),isHere?R.drawable.marker_here:R.drawable.marker_event);
			Bitmap bmp=Bitmap.createScaledBitmap(bmp0, 30, 30, true);
			canvas.drawBitmap(bmp, coor.x, coor.y, paint);
			return true;
		}
		
		public boolean onTouchEvent(MotionEvent e,MapView mapView)
		{
			EventItemWindow.requestUpdate(SearchEvents.this);
			return true;
		}
	}
	
	public GeoPoint[] getGPSSpan()
	{
		GeoPoint gp=mv.getProjection().fromPixels(0, 0);
		int right=gp.getLongitudeE6()+mv.getLongitudeSpan();
		int bottom=gp.getLatitudeE6()+mv.getLatitudeSpan();
		//GeoPoint gp2=new GeoPoint(bottom,right);
		GeoPoint gp3=mv.getProjection().fromPixels(320, 480);
		Log.e("top","Top "+gp.getLongitudeE6());
		Log.e("bottom","Bottom "+gp3.getLatitudeE6());
		Log.e("left","Left "+gp.getLongitudeE6());
		Log.e("right","Right "+gp3.getLongitudeE6());
		
		
		
		return new GeoPoint[]{gp,gp3};
	}

	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		detector.onTouchEvent(event);
		return true;
	}
	
	public void setEvents(List<Event> events)
	{
		this.events=new ArrayList<Event>();
		for(int i=0;i<events.size();i++)
			this.events.add(events.get(i));
		showEvents();
	}
	
	public void showEvents()
	{
		List<Overlay> list=mv.getOverlays();
		List<GeoPoint> geos=new ArrayList<GeoPoint>();
		for(int i=0;i<events.size();i++)
		{
			basicClass.Location eloc=events.get(i).getLocation();
			geos.add(new GeoPoint((int)(eloc.getLatitude()*1E6),(int)(eloc.getLongtitude()*1E6)));
			list.add(new LocationOverlay(false,geos.get(i)));
		}
		
		
		this.refreshMap();
		
	}

}
