package kz.istt.locust;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

/*import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.CoreProtocolPNames;*/
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.Semaphore;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import tctable.TCTable;

//import org.apache.http.entity.MultipartEntity;

/** Синхронизация данных с сервером
 * Нужно сделать глобальным
 * */
public class MySynchronizationOld
{
	//public static String URL="https://ccalm.org";
	public static String URL="http://192.168.200.100:8080";

	private Context _context; //От какого контекста показывать алерты
	//private boolean _showAlert; //Показывать ли окно подождите пожалуйста (его нельзя создавать если в сервисе)
	//public ProgressDialog dialog;

	public MyThread myThread = null;

	private int rid_sendFrmLocust = -1; //Для отправки данных
	private int rid_sendFrmLocustDel = -1; //Для отправки данных
	private int rid_frmlocust = -1; //Для запроса данных
	private int rid_frmlocustdel = -1; //Для запроса данных

	private int rid_Borns = -1;
	private int rid_countries=-1; //Для идентификации прихода данных списка стран
	private int rid_CountriesRegions = -1; //Для идентификации прихода данных списка регионов
	private int rid__languages = -1;
	private int rid__translations = -1;
	private int rid_LocustsTypes = -1; //Виды саранчи
	private int rid_list_density = -1;
	private int rid_list_directions = -1; //Стороны света (направления)
	private int rid_list_phase = -1;
	private int rid_sprayers = -1;
	private int rid_sprayers_types = -1;
	private int rid_Fledgling = -1; //Окрыление
	private int rid_list_damage = -1;
	private int rid_list_mortality = -1; //Метод подсчёта смертности (визуальный либо учётная рамка)
	private int rid_list_greenery = -1; //Состояние растительности
	private int rid_list_biotope = -1;
	private int rid_list_cover = -1;
	private int rid_list_age = -1;
	private int rid_list_actions = -1;
	private int rid_list_paintings = -1;
	private int rid_list_behaviors = -1;
	private int rid_list_breeding = -1;
	//int rid_list_operatorstypes = -1;
	private int rid_list_capacities = -1;
	private int rid_list_markings = -1;
	private int rid_list_containers = -1; //Что сделали с пустыми контейнерами от отравы
	private int rid_list_vegetation = -1;
	private int rid_list_formulation = -1;
	private int rid_list_height = -1;
	private int rid_list_enemies = -1;
	private int rid_list_purpose = -1;
	private int rid_list_impact = -1;
	private int rid_list_diluted = -1;
	private int rid_terminals = -1; //На кого зарегистрирован данныей планшет
	private int rid_companies = -1;

	MySynchronizationOld(Context context)
	{
		_context = context;

		String appPath = _context.getApplicationContext().getFilesDir().getAbsolutePath();
		//Thread for downloading from Internet
		myThread = new MyThread(this, appPath);
		myThread.start(); //Стартуем поток
	}

	/*public static HttpClient getTestHttpClient() {
		try {
			SSLContextBuilder builder = new SSLContextBuilder();
			builder.loadTrustMaterial(null, new TrustStrategy() {
				@Override
				public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return true;
				}
			});
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier());
			CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			return httpclient;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	}*/

	public int getCount()
	{
		if(myThread!=null)
			return myThread.getCountTasks();
		else
			return 0;
	}

	/** Отправить анкету саранчи на сервер по идентификатору либо по времени создания (время должно быть уникальным)
	 * */
	public void sendFrmLocust(String uid)
	{
		if(uid==null || uid=="") return;

		String xml="";
		DbOpenHelper dboh = new DbOpenHelper(_context);
		Cursor cursor = null;
		cursor = dboh.getReadableDatabase().rawQuery("select * from frmlocust where uid=?", new String[] { String.valueOf(uid) });

		if(cursor.moveToFirst())
		{
			do{
				//Если задано имя файла то добавляем его в очередь на отправку на сервер
				String fname;
				fname=cursor.getString(cursor.getColumnIndex("image_name1"));
				if(fname!=null && !fname.equals(""))
					myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);

				fname = cursor.getString(cursor.getColumnIndex("image_name2"));
				if(fname!=null && !fname.equals(""))
					myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);

				fname = cursor.getString(cursor.getColumnIndex("image_name3"));
				if(fname!=null && !fname.equals(""))
					myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);

				xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
				xml+="<metadata fn=\"4\">";
				for(int i=0;i<cursor.getColumnCount();i++)
				{
					String val="";
					if(!cursor.isNull(i)) {
						if (cursor.getType(i) == 2) { //Because cutting double
							val = "" + cursor.getDouble(i);
						} else {
							val = cursor.getString(i);
						}
					}
					xml+="	<"+cursor.getColumnName(i)+"><![CDATA["+val+"]]></"+cursor.getColumnName(i)+">\n";
				}

				String geom="";
				Cursor cursor2 = dboh.getReadableDatabase().rawQuery("select lat,lon from frmlocust_locations where frmlocust_uid=? order by pos", new String[] { String.valueOf(uid) });
				if(cursor2.moveToFirst()) {
					String first="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"]";
					do {
						geom+="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"],";
					}while (cursor2.moveToNext());
					geom += first;
					geom="{\"type\":\"Polygon\",\"coordinates\":[["+geom+"]]}";
				}
				xml+="	<geom><![CDATA["+geom+"]]></geom>";
				cursor2.close();
				xml+="</metadata>";

				rid_sendFrmLocust = myThread.addRequest(MySynchronizationOld.URL+"/get/", xml, null);

			}while (cursor.moveToNext());
		}
		cursor.close();
		dboh.close();
	}

	/**
	 * Отправить форму уничтожения саранчи из базы по идентификатору из базы
	 * @param uid
	 */
	public void sendFrmLocustDel(String uid)
	{
		if(uid==null || uid=="") return;

		String xml="";
		DbOpenHelper dboh = new DbOpenHelper(_context);
		Cursor cursor = null;
		cursor = dboh.getReadableDatabase().rawQuery("select * from frmlocustdel where uid=?", new String[] { String.valueOf(uid) });

		if(cursor.moveToFirst())
		{
			do{
				//Если задано имя файла то добавляем его в очередь на отправку на сервер
				String fname;
				fname=cursor.getString(cursor.getColumnIndex("image_name1"));
				if(fname!=null && !fname.equals(""))
					myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);

				fname = cursor.getString(cursor.getColumnIndex("image_name2"));
				if(fname!=null && !fname.equals(""))
					myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);

				fname = cursor.getString(cursor.getColumnIndex("image_name3"));
				if(fname!=null && !fname.equals(""))
					myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);


				xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
				xml+="<metadata fn=\"5\">";
				for(int i=0;i<cursor.getColumnCount();i++)
				{
					String val="";
					if(!cursor.isNull(i)) {
						if (cursor.getType(i) == 2) { //Because cutting double
							val = "" + cursor.getDouble(i);
						} else {
							val = cursor.getString(i);
						}
					}
					xml+="	<"+cursor.getColumnName(i)+"><![CDATA["+val+"]]></"+cursor.getColumnName(i)+">\n";
				}
				String geom="";
				Cursor cursor2 = dboh.getReadableDatabase().rawQuery("select lat,lon from frmlocustdel_locations where frmlocustdel_uid=? order by pos", new String[] { String.valueOf(uid) });
				if(cursor2.moveToFirst()) {
					String first="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"]";
					do {
						geom+="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"],";
					}while (cursor2.moveToNext());
					geom += first;
					geom="{\"type\":\"Polygon\",\"coordinates\":[["+geom+"]]}";
				}
				xml+="	<geom><![CDATA["+geom+"]]></geom>";
				cursor2.close();
				xml+="</metadata>";

				rid_sendFrmLocustDel = myThread.addRequest(MySynchronizationOld.URL+"/get/", xml, null);

			}while (cursor.moveToNext());
		}
		cursor.close();
		dboh.close();
	}

	//Для обновления справочников
	int makeRequest(String tableName)
	{
		String seq="";
		DbOpenHelper dboh = new DbOpenHelper(_context);
		SQLiteDatabase db = dboh.getReadableDatabase();
		Cursor cursor = db.rawQuery("select max(seq) as seq from " + tableName + ";", null);
		if (cursor.moveToFirst()) {
			seq = cursor.getString(cursor.getColumnIndex("seq"));
		}
		if (seq == null) seq = "0";
		cursor.close();
		dboh.close();
		return myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=1&r=0&n="+tableName+"&s=" + seq + "&l=1000","", null);
	}


	/**
	 * Синхронизовать данные с сервером (добавляет задания в поток)
	 * Если в задании синхронизации есть хоть 1 задание не должно синхронизироваться
	 * boolean bAll - Синхронизировать ли всё (задания и пользователи запрашиваются при запуске программы)
	 */
	public void Synch()
	{
		if(myThread.getCountTasks()!=0)
			return; //Не начинать новую синхронизацию текущая не закончилась (так мы защищаемся от повторной отправки)

		String xml="";

		//Последовательно отправляю изменёные пользователям записи (send=0 и они заполнены)
		DbOpenHelper dboh = new DbOpenHelper(_context);
		Cursor cursor = dboh.getReadableDatabase().rawQuery("select uid from frmlocust where send=0 and filled=1", null);
		if(cursor.moveToFirst())
		{
			do{
				sendFrmLocust(cursor.getString(cursor.getColumnIndex("uid")));
			}while (cursor.moveToNext());
		}
		cursor.close();
		dboh.close();

		//Последовательно отправляю изменёные пользователям записи (send=0 и они заполнены)
		dboh = new DbOpenHelper(_context);
		cursor = dboh.getReadableDatabase().rawQuery("select uid from frmlocustdel where send=0 and filled=1", null);
		if(cursor.moveToFirst())
		{
			do{
				sendFrmLocustDel(cursor.getString(cursor.getColumnIndex("uid")));
			}while (cursor.moveToNext());
		}
		cursor.close();
		dboh.close();

		//Запрос в очередь на получение списка стран, направлений, итд.
		rid_LocustsTypes = makeRequest("locuststypes");
		rid_sprayers = makeRequest("sprayers");
		rid_sprayers_types = makeRequest("sprayers_types");
		rid_Fledgling = makeRequest("fledgling");
		rid_list_density = makeRequest("list_density");
		rid_list_phase = makeRequest("list_phase");
		rid_list_directions = makeRequest("list_directions"); //Стороны света (направления)
		rid_list_damage = makeRequest("list_damage"); //Справочник степень повреждения растительного покрова
		rid_list_mortality = makeRequest("list_mortality"); //Справочник степень повреждения растительного покрова
		rid_list_greenery = makeRequest("list_greenery");
		rid_list_biotope = makeRequest("list_biotope");
		rid_list_cover = makeRequest("list_cover");
		rid_list_age = makeRequest("list_age");
		rid_list_actions = makeRequest("list_actions");
		rid_list_paintings = makeRequest("list_paintings");
		rid_list_behaviors = makeRequest("list_behaviors");
		rid_list_breeding = makeRequest("list_breeding");
		rid_list_capacities = makeRequest("list_capacities");
		rid_list_markings = makeRequest("list_markings");
		rid_list_containers = makeRequest("list_containers");
		rid_list_vegetation = makeRequest("list_vegetation");
		rid_list_formulation = makeRequest("list_formulation");
		rid_list_height = makeRequest("list_height");
		rid_list_enemies = makeRequest("list_enemies");
		rid_list_purpose = makeRequest("list_purpose");
		rid_list_impact = makeRequest("list_impact");
		rid_list_diluted = makeRequest("list_diluted");
		rid_terminals  = makeRequest("terminals");
		rid_companies  = makeRequest("companies");

        rid_countries = makeRequest("countries"); //Если есть хоть 1 запись то считается что справояники хоть 1 раз загрузились
		rid_CountriesRegions = makeRequest("countriesregions");

		rid__languages = makeRequest("_languages");
		rid__translations = makeRequest("_translations");

		rid_Borns = makeRequest("borns");  //Справочник отрождение "Начало", "Массовое".
	}

	//Пришел ответ от HTTP сервера
	//Если резутьтат true то сохранено (данные корректны)
	//public boolean incomingData(int rid, byte[] data)
	public boolean incomingData(int rid, String filePath)
	{
		/*if (BuildConfig.DEBUG && ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) )) {
			try {
				String log=Tools.getStringFromFile(filePath,1024);
				Log.e("CCALM", log);
			}catch(Exception ex)
			{}
		}*/

		Boolean result=true;
		if(filePath==null || filePath.equals("")) return false;
		File file=new File(filePath);
		if(!file.exists()) return false;
		try
		{
			FileInputStream is=new FileInputStream(file);

			DbOpenHelper dbOpenHelper = new DbOpenHelper(_context);

			//Пока не однообразно то по идентификаторам определяем что в двоичном формате
			if((rid == rid_list_mortality && rid_list_mortality!=-1) || (rid == rid_list_damage && rid_list_damage!=-1) ||
				(rid == rid_list_directions && rid_list_directions!=-1) || (rid == rid_Fledgling && rid_Fledgling!=-1) ||
				(rid == rid_sprayers && rid_sprayers!=-1) || (rid == rid_sprayers_types && rid_sprayers_types!=-1) ||
				(rid == rid_list_phase && rid_list_phase!=-1) || (rid == rid_list_density && rid_list_density!=-1) ||
				(rid == rid_Borns && rid_Borns!=-1) || (rid == rid_LocustsTypes && rid_LocustsTypes!=-1) ||
				(rid == rid_countries && rid_countries!=-1) || (rid==rid_CountriesRegions && rid_CountriesRegions!=-1) ||
				(rid == rid__languages && rid__languages != -1) || (rid == rid__translations && rid__translations != -1) ||
				(rid == rid_frmlocust && rid_frmlocust!=-1) || (rid == rid_frmlocustdel && rid_frmlocustdel!=-1) ||
				(rid == rid_list_greenery && rid_list_greenery!=-1) || (rid == rid_list_biotope && rid_list_biotope!=-1) ||
				(rid == rid_list_cover && rid_list_cover!=-1) || (rid == rid_list_age && rid_list_age!=-1) ||
				(rid == rid_list_actions && rid_list_actions!=-1) || (rid == rid_list_paintings && rid_list_paintings!=-1) ||
				(rid == rid_list_behaviors && rid_list_behaviors!=-1) ||
				(rid == rid_list_breeding && rid_list_breeding!=-1) ||
				(rid == rid_list_capacities && rid_list_capacities!=-1) ||
				(rid == rid_list_markings && rid_list_markings!=-1) ||
				(rid == rid_list_containers && rid_list_containers!=-1) ||
				(rid == rid_list_vegetation && rid_list_vegetation!=-1) ||
				(rid == rid_list_formulation && rid_list_formulation!=-1) ||
				(rid == rid_list_height && rid_list_height!=-1) ||
				(rid == rid_list_enemies && rid_list_enemies!=-1) ||
				(rid == rid_list_purpose && rid_list_purpose!=-1) ||
				(rid == rid_list_impact && rid_list_impact!=-1) ||
				(rid == rid_list_diluted && rid_list_diluted!=-1) ||
				(rid == rid_terminals && rid_terminals!=-1) ||
				(rid == rid_companies && rid_companies!=-1)
				)
			{
				TCTable tbl=new TCTable("",0);
				if(tbl.OpenTableH(is))
				{
					result = dbOpenHelper.updateTable(tbl);
				}

			}else //Данные в виде XML файла
			{
				//Парсим файл
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				try {
					DocumentBuilder builder = factory.newDocumentBuilder();
					Document doc = null;
					try {
						doc = builder.parse(is);
					} catch (Exception e) {
						is.close();
						file.delete();
						return false;
					}

					Element root = doc.getDocumentElement();

					String fn=root.getAttribute("fn");
					if (fn.equals("-1")) {
						String error= XMLTools.getCDATAValue(root);
						Log.e("CCALM", "Error = " + error);
						//MyAlert("ASDC: Error!",XMLTools.getCDATAValue(root));
					} else if (fn.equals("1")) //Пришли данные о пользователе устройства обновим либо добавим
					{
					} else if (fn.equals("2")) //Пришли данные заданий по сбору инфы о саранче
					{
					} else if (fn.equals("3")) //Пришли данные заданий по сбору инфы об уничтожении саранчи
					{
					} else if (fn.equals("4")) //Сохранили данные о саранче на сервере ставим признак отправленности
					{
						String uid = XMLTools.getCDATAValue(XMLTools.findFirstNode(root, "uid"));
						if (uid == "" || uid == "null") uid = null;

						Cursor cursor;
						DbOpenHelper dboh = new DbOpenHelper(_context);
						SQLiteDatabase db = dboh.getReadableDatabase();

						ContentValues cv = new ContentValues();
						cv.put("send", 1); //Отмечаем как отправленное
						//cv.put("changed", 0); //Отмечаем как не измененное

						db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
						try {
							db.update("frmlocust", cv, "uid = ?", new String[]{String.valueOf(uid)});
							db.setTransactionSuccessful();
						} finally {
							db.endTransaction();
						}

						//Ищем имя файла по id и удаляем фотографии
						cursor = db.rawQuery("select image_name1, image_name2, image_name3 from frmlocust where uid=?;", new String[]{String.valueOf(uid)});
						if (cursor.moveToFirst()) {
							String path;
							File pFile;
							path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"));
							pFile = new File(path);
							if (pFile.exists()) //Переименовываю файл чтобы зановоне отправить при редактировании
							{
								pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name1"))));
							}
							path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name2"));
							pFile = new File(path);
							if (pFile.exists()) //Переименовываю файл чтобы зановоне отправить при редактировании
							{
								pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name2"))));
							}
							path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name3"));
							pFile = new File(path);
							if (pFile.exists()) //Переименовываю файл чтобы зановоне отправить при редактировании
							{
								pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name3"))));
							}
						}
						db.close();

					} else if (fn.equals("5")) //Сохранили данные о саранче на сервере ставим признак отправленности
					{
						String uid = XMLTools.getCDATAValue(XMLTools.findFirstNode(root, "uid"));
						if (uid == "" || uid == "null") uid = null;

						Cursor cursor;
						DbOpenHelper dboh = new DbOpenHelper(_context);
						SQLiteDatabase db = dboh.getReadableDatabase();

						ContentValues cv = new ContentValues();
						cv.put("send", 1); //Отмечаем как отправленное
						//cv.put("changed", 0); //Отмечаем как не измененное

						db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
						try {
							db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(uid)});
							db.setTransactionSuccessful();
						} finally {
							db.endTransaction();
						}

						//Ищем имя файла по id и удаляем фотографии
						cursor = db.rawQuery("select image_name1, image_name2, image_name3 from frmlocustdel where uid=?;", new String[]{String.valueOf(uid)});
						if (cursor.moveToFirst()) {
							String path;
							File pFile;
							path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"));
							pFile = new File(path);
							if (pFile.exists()) //Переименовываю файл чтобы заново не отправить при редактировании
							{
								pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name1"))));
							}
							path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name2"));
							pFile = new File(path);
							if (pFile.exists()) //Переименовываю файл чтобы заново не отправить при редактировании
							{
								pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name2"))));
							}
							path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name3"));
							pFile = new File(path);
							if (pFile.exists()) //Переименовываю файл чтобы заново не отправить при редактировании
							{
								pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name3"))));
							}
						}
						db.close();

					} else if (fn.equals("6")) //Фото отправлено
					{
					}

				} catch (Exception e) {
					//throw new RuntimeException(e);
					//MyAlert("ASDC: Synchronization error", e.toString());
					//Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
				}
				//if(_showAlert) dialog.dismiss();
			}


			is.close();
			file.delete();

		} catch (Exception e) {
			result = false;
		}
		return result;
	}

}

/* Поток заданий на отправку данных на сервер */
class MyThread extends Thread
{
    private int rid = 0; //Инкреминтальный номер ответа для сохранения уникальных файлов

    class Tsk //Задание отправки данных
    {
        String url = ""; //URL куда отправлять данные
        String str = ""; //Отправляемая строка
        String file = ""; //Отправляемый файл
        Boolean s = false; //Integer s = 0; // false - не отправлялось true - в процессе отправки (если ошибка то ставиться статус не отправлено иначе удаляется из списка заданий)
        int id = 0; //Инкриментальный идентификатор запроса
        int wait = 10; //Милисекунд ждать перед отправкой текущего задания
        int t=0; //Количество совершенных попыток отправки
    }

    private int mId=0; //Инкриментальный идентификатор запроса
    private Semaphore mSemaphore = null; //Семафор для доступа к списку заданий
    private ArrayList<Tsk> mTList = new ArrayList<Tsk>(); //Защищёный список
    private MySynchronizationOld mListener = null; //Для отправки ответов в основной поток
    private String mAppPath = "";

    //@SuppressLint("HandlerLeak") //Подавить предупреждения о неоптимальности
    private Handler myHandle = new Handler() //Для ловли сообщений из другого потока
    {
        @Override
        public void handleMessage(Message msg) //Слушатель ответа после отправки данных на сервер
        {
            int rid = msg.getData().getInt("id");
            //Boolean b = mListener.incomingData(rid, msg.getData().getByteArray("data")); //Слушатель должен вернуть true иниче запрос останется в очереди
            Boolean b = mListener.incomingData(rid, msg.getData().getString("file")); //Слушатель должен вернуть true иниче запрос останется в очереди

            try
            {
                mSemaphore.acquire();
                for(int i=0; i<mTList.size();i++)
                {
                    if(mTList.get(i).id==rid)
                    {
                        if(b) //Удаляем обработанное заданин по id
                        {	mTList.remove(i);
                            break;
                        }else //Не обработаное пытаемся отправить заново (но увеличив ожидание перед повтором прохода заданий на 5 минут но не больше чем раз в 30 минут)
                        {
                            mTList.get(i).wait += 1000 * 60  * 5; //Увеличиваем ожидание перед новой отправкой на 5 минут
                            if(mTList.get(i).wait > 1000 * 60 * 30 ) mTList.get(i).wait = 1000 * 60 * 30; //Ограничение 30 минут
                            mTList.get(i).s = false; //Отмечаем как не отправленное
                            mTList.get(i).t++; //Увиличиваем счётчик количество попыток отправки
                            if(mTList.get(i).t>10) mTList.remove(i); //Удаляем задание после 10 попыток отправки
                            break;
                        }
                    }
                }

            } catch (InterruptedException ex)
            {
            } finally
            {	mSemaphore.release();
            }

        }
    };

    public MyThread(MySynchronizationOld listener, String appPath)
    {
        mListener = listener;
        mAppPath = appPath;
        assert(mListener != null);

        mSemaphore = new Semaphore(1);
    }

    // Добавление в задание на отправку до того как не получен ответ от предедущего запроса следующий не отсылается те. последовательно это делает (обработка результатов не в потоке загрузки а в основном потоке)
    //return id запроса
    public int addRequest(String url, String str, String file)
    {
        mId++; //Инкрементируем идентификатор запроса
        try
        {
            mSemaphore.acquire();

            Tsk t = new Tsk();
            t.url = url;
            t.str = str;
            t.file = file;
            t.s = false;
            t.id = mId;
            mTList.add(t);
        } catch (InterruptedException ex)
        {
        } finally
        {	mSemaphore.release();
        }
        return mId;
    }

    /**
     * Получить количество заданий ожидающих выполнение
     * @return
     */
    public int getCountTasks()
    {
        int result=0;
        try
        {
            mSemaphore.acquire();
            result = mTList.size();
        } catch (InterruptedException ex)
        {
        } finally
        {	mSemaphore.release();
        }
        return result;
    }

    @Override
    public void run()
    {
        Tsk tsk;
        while(true)
        {
            //Считываем первое задание из защищёного семафором списка
            tsk = null;
            try {

                mSemaphore.acquire();
                for(int i=0;i<mTList.size();i++)
                {
                    if(! mTList.get(i).s)
                    {	tsk = mTList.get(i);
                        break;
                    }
                }
            } catch (InterruptedException ex) {
                // вот такое может произойти, если поток например прервут thread.interrupt()
            } finally {
                mSemaphore.release(); //Отдаем семафор
            }

            //Выполняем задание на отправку/приём данных
            if(tsk != null)
            {
                boolean bError=false;
                tsk.s = true; //Признак отправляемости запроса на сервер

                try {
                    sleep(tsk.wait); //Если в задании задано сколько подождать перед запуском
                } catch (InterruptedException e) { }

                try
                {
					URL url = new URL(tsk.url);
					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
					conn.setReadTimeout(15000);
					conn.setConnectTimeout(15000);
					conn.setRequestMethod("POST");

					conn.setDoInput(true);
					conn.setDoOutput(true);

					if(tsk.file!=null) { //Отправляем файл на сервер
						File file = new File(tsk.file);
						if(file.exists())
						{
							String boundary = UUID.randomUUID().toString();
							String crlf = "\r\n";
							conn.setRequestProperty("Connection", "Keep-Alive");
							conn.setRequestProperty("Cache-Control", "no-cache");
							conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary);
							//Так теперь сами данные обрамлённые границей
							DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
							dos.writeBytes("--"+boundary + crlf);
							dos.writeBytes("Content-Type: image/jpeg" + crlf);
							dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + tctable.Tools.afterLast(tsk.file,"/") + "\"" + crlf);
							dos.writeBytes(crlf);
							// Read file
							byte[] buffer = new byte[1024];
							FileInputStream fileInputStream = new FileInputStream(file);
							int bytesRead = fileInputStream.read(buffer);
							try {
								while (bytesRead > 0) {
									try {
										dos.write(buffer, 0, bytesRead);
									} catch (OutOfMemoryError e) {
										e.printStackTrace();
									}
									bytesRead = fileInputStream.read(buffer);
								}
							} catch (Exception e) {
								e.printStackTrace();
							}
							fileInputStream.close();

							dos.writeBytes(crlf);
							dos.writeBytes("--"+boundary + "--" + crlf);
							dos.flush();
							dos.close();
						}
					}else{
						conn.setRequestProperty("Accept-Charset", "UTF-8");
						conn.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
						conn.setRequestProperty("Accept", "application/xml");

						OutputStream os = conn.getOutputStream();
						BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
						writer.write(tsk.str);
						writer.flush();
						writer.close();
						os.close();
					}

					int responseCode=conn.getResponseCode();
					if (responseCode == HttpsURLConnection.HTTP_OK) {
						rid++;
						String filePath = mAppPath+"/"+"data_"+ String.valueOf(rid)+".txt";

						//Так как файл может быть большим и он может не поместиться в памяти то сохраняем его на диск (допустим таблица с языками очень большая)
						try {
							BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
							BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
							int inByte;
							while ((inByte = bis.read()) != -1) bos.write(inByte);
							bis.close();
							bos.close();
						}catch(Exception ex)
						{}

						//Информирую слушателя о приёме данных
						Message msg = myHandle.obtainMessage();
						Bundle b = new Bundle();
						b.putString("file", filePath);
						b.putInt("id", tsk.id);
						msg.setData(b);
						myHandle.sendMessage(msg);
					}
				} catch (Exception ex) {
					bError = true;
					Log.i("igor", ex.toString());
				}
/*
                    HttpClient httpClient = new DefaultHttpClient();
                    httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
                    HttpPost httpPost = new HttpPost(tsk.url);
                    if(tsk.file!=null) //Отправляем файл на сервер
                    {
                        File file = new File(tsk.file);
                        if(file.exists())
                        {
                            MultipartEntity mpEntity = new MultipartEntity();
                            ContentBody cbFile = new FileBody(file, "image/jpeg");
                            mpEntity.addPart("file", cbFile);
                            httpPost.setEntity(mpEntity);
                        }
                    }else //Отправляем XML строку
                    {
                        httpPost.addHeader("Content-Type", "application/xml");

                        StringEntity entity = new StringEntity(tsk.str, "UTF-8");
                        entity.setContentType("application/xml");
                        httpPost.setEntity(entity);
                    }

                    HttpResponse response = httpClient.execute(httpPost);
                    if(response != null)
                    {
                        rid++;
                        String filePath = mAppPath+"/"+"data_"+ String.valueOf(rid)+".txt";

                        //Так как файл может быть большим и он может не поместиться в памяти то сохраняем его на диск
                        try {
                            BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
                            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
                            int inByte;
                            while ((inByte = bis.read()) != -1) bos.write(inByte);
                            bis.close();
                            bos.close();
                        }catch(Exception ex)
                        {}

                        Message msg = myHandle.obtainMessage();
                        Bundle b = new Bundle();
                        b.putString("file", filePath);
                        b.putInt("id", tsk.id);
                        msg.setData(b);
                        myHandle.sendMessage(msg);
                    }else
                        bError = true; //Если ошибка при принятии ответа


                } catch (UnsupportedEncodingException ex)
                {
                    bError = true;
                    Log.i("igor", "Error 5 = " + ex.toString());
                } catch (ClientProtocolException ex)
                {
                    bError = true;
                    Log.i("igor", "Error 6 = " + ex.toString());
                } catch (IOException ex)
                {
                    bError = true;
                    Log.i("igor", "Error 7 = " + ex.toString());
                }
*/

                if(bError) //Если произошла ошибка при отправке.
                {
                    tsk.wait += 1000 * 60  * 1; //Увеличиваем ожидание перед новой отправкой на 1 минуту
                    if(tsk.wait > 1000 * 60 * 10 ) tsk.wait = 1000 * 60 * 10; //Ограничение 10 минут
                    tsk.s = false; //Отмечаем как не отправленное
                    tsk.t++; //Увеличиваем счётчик количество попыток отправки

                    if(tsk.t>10) //Удаляем задание после 10 попыток отправки
                    {
                        try {
                            mSemaphore.acquire();
                            mTList.remove(tsk);
                        } catch (InterruptedException ex)
                        {
                            // вот такое может произойти, если поток например прервут thread.interrupt()
                        } finally
                        {
                            mSemaphore.release(); //Отдаем семафор
                        }
                    }
                }

            }

            try {
                sleep(100); //Задержка между каждым выполнением задания
            } catch (InterruptedException e) { }

        }
    }

}