package fishrungames.bashgid;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import org.osmdroid.DefaultResourceProxyImpl;
import org.osmdroid.ResourceProxy;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.api.IMapController;
import org.osmdroid.api.IMapView;
import org.osmdroid.util.GeoPoint;

import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedOverlay;

import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.OverlayItem.HotspotPlace;

import fishrungames.bashgid.core.ArticleManager.ArticleFullData;
import fishrungames.bashgid.core.ArticleManager.ArticleRecordData;
import fishrungames.bashgid.core.DatabaseGetArticleTask;
import fishrungames.bashgid.core.DatabaseGetGeoJournalListTask;
import fishrungames.bashgid.core.DatabaseGetJournalTask;
import fishrungames.bashgid.core.JournalManager.JournalRecordData;
import fishrungames.bashgid.core.LocationHolder;
import fishrungames.bashgid.core.JournalManager.JournalSemiFullData;
import fishrungames.networkutils.ImageManager;

public class OsmMapHolderFragment extends Fragment
{

	public static class DetailsOverlayItem extends OverlayItem
	{

		public String address;
		public String phone;

		public DetailsOverlayItem(String aTitle, String aSnippet, IGeoPoint aGeoPoint, String address, String phone)
		{
			super(aTitle, aSnippet, aGeoPoint);
			this.address = address;
			this.phone = phone;
		}

	}

	public static class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem>
	{

		private ArrayList<DetailsOverlayItem> mOverlayItems = new ArrayList<DetailsOverlayItem>();
		private ArrayList<String> mArticles = new ArrayList<String>();
		String journalName;
		Context context;

		public CustomItemizedOverlay(Drawable pDefaultMarker, ResourceProxy pResourceProxy, String journalName, Context context)
		{
			super(pDefaultMarker, pResourceProxy);
			this.journalName = journalName;
			this.context = context;
		}

		@Override
		protected OverlayItem createItem(int pos)
		{
			return mOverlayItems.get(pos);
		}

		@Override
		public int size()
		{
			if (mOverlayItems != null)
				return mOverlayItems.size();
			else
				return 0;
		}

		public void addOverlayItem(GeoPoint geoPoint, String articleName, String title, String imageUrl, String address, String phone)
		{

			DetailsOverlayItem item = new DetailsOverlayItem(title, imageUrl, geoPoint, address, phone);
			item.setMarker(MainActivity.getInstance().getResources().getDrawable(R.drawable.marker_default));
			item.setMarkerHotspot(HotspotPlace.CENTER);

			mOverlayItems.add(item);
			mArticles.add(articleName);

			populateNow();
		}

		public void populateNow()
		{
			populate();
		}

		@Override
		public boolean onSnapToItem(int arg0, int arg1, Point arg2, IMapView arg3)
		{
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		protected boolean onTap(final int index)
		{
			DetailsOverlayItem item = mOverlayItems.get(index);
			AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.getInstance());
			dialog.setTitle(item.getTitle());

			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			View dialogInnerView = inflater.inflate(R.layout.osm_dialog, null, false);

			ImageView image = (ImageView) dialogInnerView.findViewById(R.id.imageView);
			TextView textView = (TextView) dialogInnerView.findViewById(R.id.addressTextView);
			TextView hintTextView = (TextView) dialogInnerView.findViewById(R.id.hintTextView);

			Button button = (Button) dialogInnerView.findViewById(R.id.button);

			ImageManager.getInstance().ApplyImageToImageView(image, item.getSnippet());

			if (item.address.length() > 0)
			{
				final String address = item.address;

				textView.setText(address);
				textView.setVisibility(View.VISIBLE);
				hintTextView.setVisibility(View.VISIBLE);

				final String copied_text = MainActivity.getInstance().getResources().getString(R.string.copied_text);

				textView.setOnLongClickListener(new OnLongClickListener()
				{

					@Override
					public boolean onLongClick(View v)
					{

						if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
						{
							android.text.ClipboardManager clipboard = (android.text.ClipboardManager) MainActivity.getInstance().getSystemService(
									Context.CLIPBOARD_SERVICE);
							clipboard.setText(address);
						} else
						{
							android.content.ClipboardManager clipboard = (android.content.ClipboardManager) MainActivity.getInstance().getSystemService(
									Context.CLIPBOARD_SERVICE);
							android.content.ClipData clip = android.content.ClipData.newPlainText(copied_text, address);
							clipboard.setPrimaryClip(clip);
						}

						CharSequence text = MainActivity.getInstance().getResources().getString(R.string.text_is_copied);
						Toast toast = Toast.makeText(MainActivity.getInstance(), text, Toast.LENGTH_SHORT);
						toast.show();

						return true;
					}

				});
			} else
			{
				textView.setVisibility(View.GONE);
				hintTextView.setVisibility(View.GONE);
			}

			if (item.phone.length() > 0)
			{
				final String phone = item.phone;
				button.setText(phone);
				button.setVisibility(View.VISIBLE);

				button.setOnClickListener(new OnClickListener()
				{

					@Override
					public void onClick(View v)
					{
						String uri = "tel:" + phone;
						Intent intent = new Intent(Intent.ACTION_DIAL);
						intent.setData(Uri.parse(uri));
						MainActivity.getInstance().startActivity(intent);
					}

				});

			} else
			{
				button.setVisibility(View.GONE);
			}

			dialog.setView(dialogInnerView);

			dialog.setPositiveButton(R.string.dialog_open, new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int id)
				{
					if (journalName != null && journalName.length() > 0)
					{
						MainActivity.getInstance().SetLastMapFilterName(journalName);
						MainActivity.getInstance().OpenArticleScreen(mArticles.get(index), MainActivity.TAG_BACK_TO_MAPFRAGMENT);
					} else
					{
						MainActivity.getInstance().OpenArticleScreen(mArticles.get(index), MainActivity.TAG_BACK_TO_MAINFRAGMENT);
					}
				}
			});

			dialog.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int id)
				{
					dialog.cancel();
				}
			});

			dialog.show();

			return true;
		}
	}

	public static class NoInteractionOverlay extends ItemizedOverlay<OverlayItem>
	{
		private ArrayList<OverlayItem> mOverlayItems = new ArrayList<OverlayItem>();

		public NoInteractionOverlay(Drawable pDefaultMarker, ResourceProxy pResourceProxy)
		{
			super(pDefaultMarker, pResourceProxy);
		}

		@Override
		protected OverlayItem createItem(int pos)
		{
			return mOverlayItems.get(pos);
		}

		@Override
		public int size()
		{
			if (mOverlayItems != null)
				return mOverlayItems.size();
			else
				return 0;
		}

		public void addOverlayItem(GeoPoint geoPoint)
		{

			OverlayItem item = new OverlayItem("", "", geoPoint);
			item.setMarker(MainActivity.getInstance().getResources().getDrawable(R.drawable.marker_default));
			item.setMarkerHotspot(HotspotPlace.CENTER);

			mOverlayItems.add(item);

			populateNow();
		}

		public void populateNow()
		{
			populate();
		}

		@Override
		public boolean onSnapToItem(int arg0, int arg1, Point arg2, IMapView arg3)
		{
			return false;
		}

	}

	CustomItemizedOverlay itemizedOverlay;

	String filter;

	ArrayList<JournalRecordData> availableGeoJournals;
	ArrayList<String> availableGeoJournalNames;

	ArrayAdapter<String> spinnerAdapter;

	JournalSemiFullData journal;
	ArticleFullData article;

	int filterType;

	Spinner spinner;
	MapView mapView;
	TextView titleTextView;

	public OsmMapHolderFragment()
	{
		journal = null;
		article = null;
		filter = "";
		filterType = 0;
		availableGeoJournals = new ArrayList<JournalRecordData>();
		availableGeoJournalNames = new ArrayList<String>();

	}

	public OsmMapHolderFragment(int filterType, String filter)
	{
		this.journal = null;
		this.article = null;
		this.filter = filter;
		this.filterType = filterType;

		availableGeoJournals = new ArrayList<JournalRecordData>();
		availableGeoJournalNames = new ArrayList<String>();

	}

	public OsmMapHolderFragment(ArticleFullData article)
	{
		this.filter = article.name;
		this.filterType = 1;

		this.article = article;
		this.journal = null;

		availableGeoJournals = new ArrayList<JournalRecordData>();
		availableGeoJournalNames = new ArrayList<String>();

	}

	@Override
	public void onSaveInstanceState(final Bundle outState)
	{
		super.onSaveInstanceState(outState);
		outState.putString("filter", filter);
		outState.putInt("filterType", filterType);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
	{

		if (savedInstanceState != null)
		{
			filter = savedInstanceState.getString("filter");
			filterType = savedInstanceState.getInt("filterType");
		}

		View rootView = inflater.inflate(R.layout.fragment_osm_map_page, container, false);

		titleTextView = (TextView) rootView.findViewById(R.id.titleTextView);

		mapView = (MapView) rootView.findViewById(R.id.mapview);

		mapView.setMaxZoomLevel(20);
		mapView.setMinZoomLevel(4);

		mapView.setBuiltInZoomControls(true);
		mapView.setMultiTouchControls(true);

		IMapController mapController = mapView.getController();

		GeoPoint center = new GeoPoint(LocationHolder.CONST_UFA_LATITUDE, LocationHolder.CONST_UFA_LONGITUDE);

		mapController.setZoom(10);
		mapController.animateTo(center);

		RefreshView();

		spinnerAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, availableGeoJournalNames);

		spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

		spinner = (Spinner) rootView.findViewById(R.id.spinner);

		spinner.setAdapter(spinnerAdapter);

		spinner.setOnItemSelectedListener(new OnItemSelectedListener()
		{

			@Override
			public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
			{

				if (position < availableGeoJournals.size())
				{
					if (!(filterType == 0 && filter.equals(availableGeoJournals.get(position).name)))
					{

						filterType = 0;
						filter = availableGeoJournals.get(position).name;
						titleTextView.setText(R.string.map_is_loading);
						RestoreJournalOrArticle();
					}
				}

			}

			@Override
			public void onNothingSelected(AdapterView<?> parent)
			{
			}

		});

		if ((filterType == 0 && journal == null) || (filterType == 1 && article == null))
		{
			titleTextView.setText(R.string.map_is_loading);

			RestoreJournalOrArticle();

		} else
		{
			titleTextView.setText(R.string.map_is_loaded);
			RestoreGeoJournals();
		}

		return rootView;
	}

	void RestoreJournalOrArticle()
	{
		if (filterType == 0)
		{
			RestoreJournal();
		} else
		{
			RestoreArticle();
		}
	}

	void RestoreJournal()
	{

		DatabaseGetJournalTask task = new DatabaseGetJournalTask();

		task.mHandler = MainActivity.getInstance().mHandler;

		Bundle bundle = new Bundle();

		bundle.putString("journalName", filter);

		task.execute(bundle);

		availableGeoJournals.clear();
		availableGeoJournalNames.clear();
		spinnerAdapter.notifyDataSetChanged();

	}

	void RestoreArticle()
	{

		DatabaseGetArticleTask task = new DatabaseGetArticleTask();

		task.mHandler = MainActivity.getInstance().mHandler;

		task.execute(filter);

		availableGeoJournals.clear();
		availableGeoJournalNames.clear();
		spinnerAdapter.notifyDataSetChanged();

	}

	void RestoreGeoJournals()
	{

		DatabaseGetGeoJournalListTask task = new DatabaseGetGeoJournalListTask();

		task.mHandler = MainActivity.getInstance().mHandler;

		task.execute();

	}

	public void SetJournal(JournalSemiFullData journal)
	{
		filterType = 0;

		titleTextView.setText(R.string.map_is_loaded);

		this.journal = journal;

		RefreshView();

		RestoreGeoJournals();

	}

	public void SetArticle(ArticleFullData article)
	{
		filterType = 1;

		titleTextView.setText(R.string.map_is_loaded);

		this.article = article;

		RefreshView();

		RestoreGeoJournals();

	}

	public void SetGeoJournals(ArrayList<JournalRecordData> availableGeoJournals)
	{

		this.availableGeoJournals = availableGeoJournals;
		availableGeoJournalNames.clear();

		int selection = -1;

		for (JournalRecordData journal : availableGeoJournals)
		{
			if (filterType == 0 && filter.equals(journal.name))
			{
				selection = availableGeoJournalNames.size();
			}

			availableGeoJournalNames.add(journal.title);

		}

		if (filterType == 1)
		{
			selection = availableGeoJournalNames.size();
			availableGeoJournalNames.add(article.title);
		}

		spinnerAdapter.notifyDataSetChanged();

		if (selection != -1)
		{
			spinner.setSelection(selection);
		}

	}

	public void RefreshView()
	{

		ResourceProxy resourceProxy = new DefaultResourceProxyImpl(getActivity());

		itemizedOverlay = new CustomItemizedOverlay(getResources().getDrawable(R.drawable.russia_icon), resourceProxy, filter, getActivity());

		if (filterType == 0)
		{
			if (journal != null)
			{

				for (int i = 0; i < journal.articleArr.size(); i++)
				{
					ArticleRecordData article = journal.articleArr.get(i);

					if (article.geoLat != 0 || article.geoLon != 0)
					{
						GeoPoint markerPoint = new GeoPoint(article.geoLat, article.geoLon);

						itemizedOverlay.addOverlayItem(markerPoint, article.name, article.title, journal.articleArr.get(i).previewImageUrl, article.address,
								article.phone);

					}
				}
			}

		} else
		{
			if (article != null)
			{

				if (article.geoLat != 0 || article.geoLon != 0)
				{
					GeoPoint markerPoint = new GeoPoint(article.geoLat, article.geoLon);

					String imageUrl = "R.drawable.no_picture";

					if (article.albumArr.size() > 0)
					{
						if (article.albumArr.get(0).photoRecordArr.size() > 0)
						{
							imageUrl = article.albumArr.get(0).photoRecordArr.get(0).imageUrl;
						}
					}

					itemizedOverlay.addOverlayItem(markerPoint, article.name, article.title, imageUrl, article.address, article.phone);

				}

			}
		}

		mapView.getOverlays().clear();
		mapView.getOverlays().add(itemizedOverlay);

		mapView.invalidate();

	}

}
