package kz.istt.locust;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Spinner;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/*
import java.util.Locale;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
*/
public class Tools 
{
	// Чтение строки из InputStream
	public static String readInputStream(InputStream is) {
		try {
			byte[] buffer = new byte[1024];
			StringBuilder result = new StringBuilder(1024);
			int length;
			while ((length = is.read(buffer)) != -1) {
				result.append(new String(buffer, 0, length, "UTF-8")); // StandardCharsets.UTF_8.name() > JDK 7
			}
			return result.toString();
		} catch (IOException e) {
			return null;
		}
	}

	public static Date getDateFromStr(String str) {
		if(str==null)
			return null;
		Date date=null;
		try {
			date = new Date(Long.parseLong(str)*1000);
		} catch (NumberFormatException e) {
		}
		if(date==null){
			try {
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				date = format.parse(str);
			} catch (ParseException e) {
			}
		}
		return date;
	}
	//Преобразую в подходящий формат для PostgreSQL
	public static String dateToStr(Date date){
		if(date==null)
			return null;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return format.format(date);
	}

	public static Date setYMD(Date date, int year, int monthOfYear, int dayOfMonth){
		if(date==null)
			date=new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, monthOfYear - 1); // Месяцы в Calendar начинаются с 0 (январь)
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		return calendar.getTime();
	}

	public static Date setHMS(Date date, int hourOfDay, int minute,int second){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, second);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	// Преобразование из локального времени пользователя во время по Гринвичу (UTC)
	/*public static Date toUTCDate(Date localDate) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(localDate);
		calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
		return calendar.getTime();
	}

	// Преобразование из времени по Гринвичу (UTC) в локальное время пользователя
	public static Date toLocalDate(Date utcDate) {
		Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
		calendar.setTime(utcDate);
		calendar.setTimeZone(TimeZone.getDefault());
		return calendar.getTime();
	}*/

	public static boolean setListViewHeightBasedOnItems(ListView listView) {

		ListAdapter listAdapter = listView.getAdapter();
		if (listAdapter != null) {

			int numberOfItems = listAdapter.getCount();

			// Get total height of all items.
			int totalItemsHeight = 0;
			for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
				View item = listAdapter.getView(itemPos, null, listView);
				float px = 500 * (listView.getResources().getDisplayMetrics().density);
				item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
				totalItemsHeight += item.getMeasuredHeight();
			}

			// Get total height of all item dividers.
			int totalDividersHeight = listView.getDividerHeight() *
					(numberOfItems - 1);
			// Get padding
			int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();

			// Set list height.
			ViewGroup.LayoutParams params = listView.getLayoutParams();
			params.height = totalItemsHeight + totalDividersHeight + totalPadding;
			listView.setLayoutParams(params);
			listView.requestLayout();
			return true;

		} else {
			return false;
		}
	}

	//Получить текущую временную зону в виде 00:00:00
	public static String getTimezone()
	{
		Calendar cal = Calendar.getInstance();
		TimeZone tz = cal.getTimeZone();
		int offset=tz.getRawOffset()/1000;

		int hours = offset / 3600;
		int minutes = (offset % 3600) / 60;
		int seconds = offset % 60;

		return Tools.numConvert(String.format("%02d:%02d:%02d", hours, minutes, seconds));
	}

	//Преобразовать арабские и индийские в современные цифры
	public static String numConvert(String str)
	{
		if(str==null) return null;
		String persian = "۰۱۲۳۴۵۶۷۸۹";
		String arabic = "٩٨٧٦٥٤٣٢١٠";
		String num = "0123456789";
		//Заменяю персидские
		for(int i=0;i<str.length();i++)
		{
			for(int j=0;j<persian.length();j++)
			{
				if(str.charAt(i)==persian.charAt(j))
				{
					str = str.substring(0,i) + num.charAt(j) + str.substring(i+1);
					break;
				}
			}
		}
		//Заменяю арабские
		for(int i=0;i<str.length();i++)
		{
			for(int j=0;j<arabic.length();j++)
			{
				if(str.charAt(i)==arabic.charAt(j))
				{
					str = str.substring(0,i) + num.charAt(j) + str.substring(i+1);
					break;
				}
			}
		}
		return str;
	}

	public static String convertStreamToString(InputStream is, int size) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder(1024);
		String line = null;
		while ((line = reader.readLine()) != null) {
			sb.append(line).append("\n");
			if(size!=-1 && sb.length()>size)
				break;
		}
		reader.close();
		return sb.toString();
	}

	public static String getStringFromFile (String filePath, int size) throws Exception {
		File fl = new File(filePath);
		FileInputStream fin = new FileInputStream(fl);
		String ret = convertStreamToString(fin,size);
		//Make sure you close all streams.
		fin.close();
		return ret;
	}

	public static final String md5(final String str)
	{
		try {
			// Create MD5 Hash
			MessageDigest digest = java.security.MessageDigest
					.getInstance("MD5");
			digest.update(str.getBytes());
			byte messageDigest[] = digest.digest();

			// Create Hex String
			StringBuffer hexString = new StringBuffer();
			for (int i = 0; i < messageDigest.length; i++) {
				String h = Integer.toHexString(0xFF & messageDigest[i]);
				while (h.length() < 2)
					h = "0" + h;
				hexString.append(h);
			}
			return hexString.toString();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * Получить Integer из текста
	 */
	public static Boolean getBoolean(String val)
	{
		if(val==null || val.equals("") || val.equals("null")) return null;
		if(val.equals("1") || val.equals("t")) return Boolean.valueOf(true);
		if(val.equals("0") || val.equals("f")) return Boolean.valueOf(false);
		return null;
	}

	/**
	 * Получить Integer из текста
	 */
	public static Integer getInt(String val)
	{
		if(val==null || val.equals("") || val.equals("null")) return null;
		return Integer.parseInt(val);
	}
	/**
	 * Получить Long из текста
	 */
	public static Long getLong(String val, Long def)
	{
		if(val==null || val.equals("") || val.equals("null")) return def;
		return Long.parseLong(val);
	}
	/**
	 * Получить Double из текста
	 */
	public static Double getDouble(String val, Double def)
	{
		if(val==null || val.equals("") || val.equals("null")) return def;
		return Double.parseDouble(val);
	}

	/**
	 * вывод в лог данных из курсора
	 * @param c - открытый курсор
	 */
	public static void logCursor(Cursor c)
	{
		Log.d("LOG_TAG", "Cursor:");
		if (c != null)
		{
			if (c.moveToFirst())
			{
				String str;
				do {
					str = "";
					for (String cn : c.getColumnNames())
					{
						str = str.concat(cn + " = " + c.getString(c.getColumnIndex(cn)) + "; ");
					}
					Log.d("LOG_TAG", str);
				} while (c.moveToNext());
			}
		} else
			Log.d("LOG_TAG", "Cursor is null");
	}

	/**
	 * Выбрать в списке по названию если нет то создать элемент в конце списка
	 * @param item название
	 */
	public static void selSpinnerIC(Spinner spi, String item)
	{
		if(item == null) item = "";
		int pos=-1;
		for(int i=0;i<spi.getCount();i++)
		{
			if(spi.getItemAtPosition(i).toString().equals(item))
			{	pos = i;
				break;
			}
		}
		if(pos==-1)
		{
			ArrayAdapter<String> dataAdapter = (ArrayAdapter<String>)spi.getAdapter();
			//SpinnerAdapter  dataAdapter = spi.getAdapter();
			if(dataAdapter!=null)
			{	dataAdapter.add(item);
				pos=spi.getCount()-1;
			}//else pos=INVALID_POSITION;
		}
		spi.setSelection(pos);
	}

	//Загрузка ранее сохраненной локали
	public static void loadLocale(Context context)
	{
		String langPref = "Language";
		SharedPreferences prefs = context.getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
		String language = prefs.getString(langPref, "");

		Tools.changeLang0(context, language);
	}

	//Сохранение текущей локали
	public static void saveLocale(Context context, String lang)
	{
		String langPref = "Language";
		SharedPreferences prefs = context.getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(langPref, lang);
		editor.commit();

		Tools.changeLang0(context,lang);
	}

	//Смена языка в приложении
	private static void changeLang0(Context context, String lang)
	{
		if (lang.equalsIgnoreCase(""))
			return;

		Locale myLocale = new Locale(lang);
		Locale.setDefault(myLocale);
		android.content.res.Configuration config = new android.content.res.Configuration();
		config.locale = myLocale;

		context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

	}

	/*Получить короткое имя языка*/
	public static String getLang()
	{
/*		android.content.res.Configuration config = new android.content.res.Configuration();
		return config.locale.getDisplayLanguage();
*/
		return Locale.getDefault().getLanguage();
	}

	/** Дату время в виде строки "HH:mm:ss dd.MM.yyyy" в секунд с 1970 года 
	 * */
	public static Long getUnixDateTime(String dateString)
	{
		SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy");
		Date convertedDate = new Date();
		try {
			convertedDate = dateFormat.parse(dateString);
		} catch (java.text.ParseException e) {
			e.printStackTrace();
			return null;
		}
		return Long.valueOf(convertedDate.getTime()/1000L); //Секунд с 1970 года
	}

	/** Время в виде строки "HH:mm:ss" в секунды 
	 * */
	public static Integer getUnixTime(String timeString)
	{
		SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
		Date convertedDate = new Date();
		try {
			convertedDate = dateFormat.parse(timeString);
		} catch (java.text.ParseException e) 
		{
			e.printStackTrace();
			return null;
		}
		return Integer.valueOf((int)(convertedDate.getTime()/1000L)); //Секунд
	}

	/** Boolean из Spinner 0 - null 1 - true 2 - false 
	 */
	public static Boolean getBooleanFromSpi(Spinner spi)
	{
		if(spi==null) return null;
		switch(spi.getSelectedItemPosition())
		{
			case 1:
				return Boolean.valueOf(true);
			case 2:
				return Boolean.valueOf(false);
		}
		return null;
	}

	//Направление ветра по номеру спинера (8 сторон света)
	public static Integer getDirection(Spinner spi)
	{
		//Направление ветра по номеру
		Integer dir=null;
		if(spi.getSelectedItemPosition()==0) dir=null;
		else if(spi.getSelectedItemPosition()==1) dir=0;
		else if(spi.getSelectedItemPosition()==2) dir=180;
		else if(spi.getSelectedItemPosition()==3) dir=270;
		else if(spi.getSelectedItemPosition()==4) dir=90;
		else if(spi.getSelectedItemPosition()==5) dir=45;
		else if(spi.getSelectedItemPosition()==6) dir=315;
		else if(spi.getSelectedItemPosition()==7) dir=135;
		else if(spi.getSelectedItemPosition()==8) dir=225;
		else
		{	dir= Integer.getInteger(spi.getSelectedItem().toString());
		}
		return dir;
	}

	//Выставить направление ветра в спинере
	public static void setDirection(Spinner spi, String dir)
	{
		if(spi == null) return;

		if(dir == null || dir.equals("")) spi.setSelection(0);
		else if(dir.equals("0")) spi.setSelection(1);
		else if(dir.equals("180")) spi.setSelection(2);
		else if(dir.equals("270")) spi.setSelection(3);
		else if(dir.equals("90")) spi.setSelection(4);
		else if(dir.equals("45")) spi.setSelection(5);
		else if(dir.equals("315")) spi.setSelection(6);
		else if(dir.equals("135")) spi.setSelection(7);
		else if(dir.equals("225")) spi.setSelection(8);
		else Tools.selSpinnerIC(spi,dir);
	}

	//Получить строку заменив NULL пустой строкой
	public static String getStringFromCursor(Cursor cursor, String name)
	{
		if(cursor==null || name==null) return "";
		String str=cursor.getString(cursor.getColumnIndex(name));
		if(str==null || str=="null") str="";
		return str.toLowerCase();
	}

	//Изменяем размер пропорционально
	public static Bitmap getResizeBMP(Bitmap bm, int newSize) {
		float newWidth;
		float newHeight;
		if(bm.getWidth()>bm.getHeight())
		{
			newWidth = newSize;
			newHeight = bm.getHeight() * ((float)newSize / bm.getWidth());
		}else
		{
			newHeight = newSize;
			newWidth = bm.getWidth() * ((float)newSize / bm.getHeight());
		}
		return getResizedBitmap(bm,(int)newWidth,(int)newHeight);
	}

	public static Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight)
	{
		int width = bm.getWidth();
		int height = bm.getHeight();

		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;
		// CREATE A MATRIX FOR THE MANIPULATION
		Matrix matrix = new Matrix();
		// RESIZE THE BIT MAP
		matrix.postScale(scaleWidth, scaleHeight);
		matrix.postRotate(90);

		// "RECREATE" THE NEW BITMAP
		Bitmap resizedBitmap = Bitmap.createBitmap(
				bm, 0, 0, width, height, matrix, false);
		bm.recycle();
		return resizedBitmap;
	}


}
