package fishrungames.bashgid.core.db;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.Semaphore;

import fishrungames.bashgid.core.NewsManager;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class NewsDataSource
{
	
	//Xperimental -- move somewhere
	public static final SimpleDateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);

	private SQLiteDatabase database = null;

	private BashgidSqliteHelper dbHelper = null;

	private String[] allColumns = { BashgidSqliteHelper.COLUMN_ID, BashgidSqliteHelper.COLUMN_TITLE, BashgidSqliteHelper.COLUMN_DESCRIPTION,
			BashgidSqliteHelper.COLUMN_IMAGE_ID, BashgidSqliteHelper.COLUMN_PUBDATE };
	
	
	private final Semaphore mutex = new Semaphore(1, true);

	public NewsDataSource(Context context)
	{
		
		try
		{
			mutex.acquire();
			try
			{
				
				dbHelper = new BashgidSqliteHelper(context);
				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when creating BashgidSqliteHelper", "Error when creating BashgidSqliteHelper");
		}
	}

	public void open() throws SQLException
	{
		try
		{
			mutex.acquire();
			try
			{
				
				database = dbHelper.getWritableDatabase();
				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when opening NewsDataSource", "Error when opening NewsDataSource");
			
			database = null;
		}
		
	}

	public void close()
	{
		try
		{
			mutex.acquire();
			try
			{
				if (dbHelper != null)
				{
					dbHelper.close();
					database = null;
				}
				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when closing NewsDataSource", "Error when closing NewsDataSource");
		}
		
	}

	public void createNewsRecord(NewsManager.NewsRecord newsRecord)
	{

		ContentValues values = new ContentValues();

		values.put(BashgidSqliteHelper.COLUMN_TITLE, newsRecord.title);
		values.put(BashgidSqliteHelper.COLUMN_DESCRIPTION, newsRecord.description);
		values.put(BashgidSqliteHelper.COLUMN_IMAGE_ID, newsRecord.imageId);
		values.put(BashgidSqliteHelper.COLUMN_PUBDATE, iso8601Format.format(newsRecord.pubDate));
		
		
		
		try
		{
			mutex.acquire();
			try
			{
				
				if (database != null)
				{
					database.insert(BashgidSqliteHelper.TABLE_NEWS, null, values);
				}
				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when calling createNewsRecord", "Error when calling createNewsRecord");
		}	
	}

	public void replaceNews(ArrayList<NewsManager.NewsRecord> newsRecordArr)
	{

		try
		{
			mutex.acquire();
			try
			{
				
				if (database != null)
				{
					database.delete(BashgidSqliteHelper.TABLE_NEWS, null, null);
				}
				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when calling replaceNews", "Error when calling replaceNews");
		}
		

		for (NewsManager.NewsRecord newsRecord : newsRecordArr)
		{
			createNewsRecord(newsRecord);
		}

	}

	public ArrayList<NewsManager.NewsRecord> getNews()
	{

		ArrayList<NewsManager.NewsRecord> newsRecordArr = new ArrayList<NewsManager.NewsRecord>();

		try
		{
			mutex.acquire();
			try
			{

				if (database != null)
				{
					Cursor cursor = database.query(BashgidSqliteHelper.TABLE_NEWS, allColumns, null, null, null, null, null);

					cursor.moveToFirst();
					
					while (!cursor.isAfterLast())
					{
						NewsManager.NewsRecord newsRecord = cursorToNewsRecord(cursor);
						newsRecordArr.add(newsRecord);
						cursor.moveToNext();
					}

					cursor.close();
				}

				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when calling getNews", "Error when calling getNews");
		}

		return newsRecordArr;
	}
	
	
	public ArrayList<NewsManager.NewsRecord> searchNewsByString(String searchText)
	{

		ArrayList<NewsManager.NewsRecord> newsRecordArr = new ArrayList<NewsManager.NewsRecord>();

		try
		{
			mutex.acquire();
			try
			{

				if (database != null)
				{
	
					Cursor cursor = database.query(true, BashgidSqliteHelper.TABLE_NEWS, allColumns, BashgidSqliteHelper.COLUMN_TITLE + " LIKE '%"+searchText+"%'", null, null, null, null, null);

					cursor.moveToFirst();
					
					while (!cursor.isAfterLast())
					{
						NewsManager.NewsRecord newsRecord = cursorToNewsRecord(cursor);
						newsRecordArr.add(newsRecord);
						cursor.moveToNext();
					}

					cursor.close();
				}

				
			} finally
			{
				mutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error when calling searchNewsByString", "Error when calling searchNewsByString");
		}

		return newsRecordArr;
	}

	private NewsManager.NewsRecord cursorToNewsRecord(Cursor cursor)
	{

		NewsManager.NewsRecord newsRecord = null;
		try
		{
			newsRecord = new NewsManager.NewsRecord(cursor.getString(1), cursor.getString(2), cursor.getString(3), iso8601Format.parse(cursor.getString(4)));
		}
		catch (ParseException e)
		{
			e.printStackTrace();
		}

		return newsRecord;
	}
}
