package org.arkiwi.app.activity;

import io.vov.vitamio.VitamioInstaller;
import io.vov.vitamio.VitamioInstaller.VitamioNotCompatibleException;
import io.vov.vitamio.VitamioInstaller.VitamioNotFoundException;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.arkiwi.app.R;
import org.arkiwi.app.adapter.AdapterGrid;
import org.arkiwi.app.database.Db;
import org.arkiwi.app.database.DbFeed;
import org.arkiwi.app.feed.FeedItem;
import org.arkiwi.app.feed.FeedItemFile;
import org.arkiwi.app.feed.FeedQuery;
import org.arkiwi.app.interfaces.SDialogInterface;
import org.arkiwi.app.rss.RssDoc;
import org.arkiwi.app.rss.RssQueryTask;
import org.arkiwi.app.rss.RssReader;
import org.arkiwi.app.service.Downloader;
import org.arkiwi.app.utility.Download;
import org.arkiwi.app.utility.IcoCtxMenu;
import org.arkiwi.app.utility.SDialog;
import org.arkiwi.app.utility.SMethod;

import com.androidhive.musicplayer.MusicPlayerActivity;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.text.ClipboardManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class Viewer extends Activity implements SDialogInterface {
	private final static String LOG_TAG = "Viewer";

	private static FeedQuery fq;
	private static ArrayList<FeedItem> fi = new ArrayList<FeedItem>();
		
	private static Resources res;
	private static Activity activity;
	private static Context ctx;
	private static GridView gridView;
	private static AdapterGrid gridAdapter;
	private static EditText pathBox;
	private static ImageView backBtn;

	private static RssReader rssReader;
	private static RssQueryTask task;
	private static RssDoc rssDocs;
	private static DbFeed db;
	//private static boolean onScreenTurn = false;
	
	public static final int INTENT_SONG_ID = 1;
	/* Menu */
	private static final int MENU_SAVEFEED_ID = 10;
	public static final int MENU_XSPF_ID = 11;
	/* Context Menu, e il Dialog che risponde al CM */
	private static int ctxMenuItemPos = -1;
	private static final int MENUCTX_ITEM_META = 1;
	//private static final int MENUCTX_ITEM_URL = 2;
	private static final int MENUCTX_ITEM_QR = 3;
	private static final int MENUCTX_ITEM_DOWN = 4;
	private static final int MENUCTX_ITEM_TORRENT = 5;
	private static IcoCtxMenu icoCtxMenu;
	private static IcoCtxMenu icoCtxMenuDir;
	private static Dialog dialog;
	/* download manager */
	private long enqueue;
	private BroadcastReceiver rcvDownload;
	private DownloadManager dm;

	private static Intent mpIntent;
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.viewer_main);
		Log.i(LOG_TAG, "onCreate()");
		res = getResources();
		gridView = (GridView) findViewById(R.id.gridView);
		backBtn = (ImageView) findViewById(R.id.backBtn);
		pathBox = (EditText) findViewById(R.id.pathBox);
		rssReader = RssReader.getInstance();
		rssDocs = RssDoc.getInstance(ATab.max_cache);
		mpIntent = new Intent(this,MusicPlayerActivity.class);
		activity = this;
		ctx = getApplicationContext();
		fq=null;
		
		RssDoc.resetNBackPress();
		@SuppressWarnings("unchecked")
		HashMap<String,Object> state = (HashMap<String, Object>) this.getLastNonConfigurationInstance();
		if (state != null) {
			rssReader.setFeedQuery((FeedQuery) state.get("grid"));
		} else if(RssReader.getFromState()==RssReader.STATE_BACK_VIEWER){
			rssReader.clearFeedQuery();
			RssReader.setFromState(RssReader.STATE_INIT_VIEWER);
		}
	}
	
	@TargetApi(Build.VERSION_CODES.GINGERBREAD)
	private void downloadManager(){
		rcvDownload = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction();
				
				if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
					Query query = new Query();
					query.setFilterById(enqueue);
					Cursor c = dm.query(query);
					if (c.moveToFirst()) {
						if (DownloadManager.STATUS_SUCCESSFUL == 
							c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
							Log.d(LOG_TAG,""+c.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI));
							Toast.makeText(ctx,
								R.string.toast_download_done, Toast.LENGTH_LONG)
								.show();
						}
					}
				}
			}
		};
		registerReceiver(rcvDownload, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
	}
	
	@TargetApi(Build.VERSION_CODES.GINGERBREAD)
	private void startDownload(String downloadUrl){
		Log.d(LOG_TAG, "download f:"+downloadUrl);
		File f = Download.getFile(downloadUrl,"downloads");
		if ( f.exists() ) {
			Toast.makeText(ctx,
					R.string.toast_file_exist+
					R.string.toast_download_blocked, Toast.LENGTH_LONG)
					.show();
		} else {
			//TODO: scaricare da Network Mobile on pref
			dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
			DownloadManager.Request req = new DownloadManager.Request(Uri.parse(downloadUrl))
				.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
				.setAllowedOverRoaming(false)
				.setDescription(getString(R.string.app_download_manager_title))
				.setDestinationUri(Uri.fromFile(f));
		
				Toast.makeText(ctx,	
					   R.string.toast_download_start, Toast.LENGTH_SHORT)
					   .show();
				enqueue = dm.enqueue(req);
		}
		
	}
	
	private static Handler download22handler = new Handler() {
		public void handleMessage(Message message) {
			Object path = message.obj;
			if (message.arg1 == RESULT_OK && path != null) {
				Toast.makeText(ctx,
						R.string.toast_download_done +": "+path.toString()
						, Toast.LENGTH_LONG)
						.show();
			} else if ( message.arg1 == RESULT_CANCELED ){
				Toast.makeText(ctx, 
						R.string.toast_download_blocked,
						Toast.LENGTH_LONG).show();
			} else {
				Toast.makeText(ctx, 
						R.string.toast_file_exist,
						Toast.LENGTH_LONG).show();
			}

		};
	};
	
	@Override
	protected void onResume() {
		super.onResume();
		Log.i(LOG_TAG, "onResume()");
		
		if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO)
			downloadManager();			
		
		RssDoc.resetNBackPress();
		fq = rssReader.getFeedQuery();
		Log.d(LOG_TAG,"state:"+RssReader.getFromState()+" fq n:"+fq.getNumFeedItem());
		if (fq.getNumFeedItem() == 0) {
			Toast.makeText(ctx,
					R.string.search_no_ricerche, Toast.LENGTH_SHORT).show();
		} else {
			if (RssReader.getFromState() == RssReader.STATE_RESUME_VIEWER) {
				gridAdapter.clearData();
				gridView.setAdapter(null);
				pathBox.setText("");
			}
			RssReader.setFromState(RssReader.STATE_RESUME_VIEWER);

			icoCtxMenu = new IcoCtxMenu(this, CTX_MENU_ID);
			icoCtxMenuDir = new IcoCtxMenu(this, CTX_MENU_ID_DIR);
			fillContextMenus();
			setCbackCtxMenu(icoCtxMenu);
			setCbackCtxMenu(icoCtxMenuDir);
			pathBox.setText(fq.getLink());
			//getBase
			fillGrid(ctx);
		}
	}
	
	public static void fillGrid(Context c){
		gridAdapter = new AdapterGrid(c);

		//da hashmap ad arraylist perchè gli adapter tornano la posizione
		//e non la stringa(key) per ottenere il feed(valore)
		hmap2alist();

		int n_feedI=fq.getNumFeedItem();
		for (int i = 0; i < n_feedI; i++) {
			FeedItem feed = fi.get(i);
			gridAdapter.addItem(feed.getTitle(), feed.getMediaType());
		}
		//Log.d(LOG_TAG, "fillGrid n:" +fq.getNumFeedItem());
		backBtn.setOnClickListener(backClickHandler);
		gridView.setOnItemClickListener(gridItemClickHandler);
		gridView.setOnItemLongClickListener(gridItemLongClickHandler);
		gridView.setAdapter(gridAdapter);
		gridAdapter.notifyDataSetChanged();
	}
	
	private static void hmap2alist(){
		if (! fi.isEmpty()){
			fi.clear();
		}
		
		Iterator<String> iterator = fq.getFeedItems().keySet().iterator();
		while (iterator.hasNext()) {
			String key = (String) iterator.next();
			fi.add(fq.getFeedItem(key));
		}
	}
	
	private static void startTask(String uri) {
		String xml = rssDocs.getDocFromCache(uri);
		RssDoc.resetNBackPress();
		if(! xml.equalsIgnoreCase("")) {
			Log.d(LOG_TAG, "startTask exist");
			rssDocs.setRss(xml,false);
			Viewer.fillGrid(ctx);
		} else {
			Log.d(LOG_TAG, "startTask NO");
			task = new RssQueryTask(activity, "view");
			task.execute(uri);
		}
	}
		
	private static OnItemClickListener gridItemClickHandler = new OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, 
				int position, long id) {
			Log.i(LOG_TAG, "gridItClick");
			ctxMenuItemPos = position;
			FeedItem feed = fi.get(position);
			String mediaType = feed.getMediaType();
			if (mediaType.equalsIgnoreCase(res.getString(R.string.rss_type_dir))) {
				//DIRECTORY
				String newPath = feed.getLink();
				rssDocs.treePushElement(newPath);
				pathBox.setText(newPath);
				startTask(newPath);	
			} else if (mediaType
				.equalsIgnoreCase(res.getString(R.string.rss_type_audio))){
				mpIntent.putExtra("type", INTENT_SONG_ID);
				mpIntent.putExtra("feed", feed.getGuid());
				activity.startActivity(mpIntent);
			} else if(mediaType
				.equalsIgnoreCase(res.getString(R.string.rss_type_video))){
				try {
				   VitamioInstaller.checkVitamioInstallation(ctx);
				   Intent i = new Intent(activity,Vitamio.class);
				   i.putExtra("stream_url", ((FeedItemFile) feed).getDownload());
				   activity.startActivity(i);
				} catch (VitamioNotCompatibleException e) {
				   activity.showDialog(DIALOG_VITAMIO_COMPATIBLE);				    	
				} catch (VitamioNotFoundException e) {
				   activity.showDialog(DIALOG_VITAMIO_NOTF);
				} 
			} else {
				Toast.makeText(ctx,	R.string.toast_bad_file, Toast.LENGTH_SHORT).show();
			}
		}
	};
	
	private static OnClickListener backClickHandler = new OnClickListener() {
		@Override
		public void onClick(View v) {
			if(isLastPop())
				Toast.makeText(ctx, R.string.toast_root, Toast.LENGTH_SHORT).show();
		}
	};

    public void managePrefFeed(){
    	db = new DbFeed(ctx);
    	db.openW();
    	int err=db.addQuery(fq);
    	switch (err) {
		case Db.DB_ERR_CONSTRAINT_ADD:
			//TODO:Attenzione può anche significare che non viene inserito
			//dato, tipo perchè bianco.
			Toast.makeText(
					ctx, R.string.toast_save_feed_exist, 
					Toast.LENGTH_SHORT).show();
			break;
		case Db.DB_ERR_GENERIC:
			Toast.makeText(
					ctx, R.string.toast_save_feed_dberr, 
					Toast.LENGTH_SHORT).show();
			break;
		default:
			Toast.makeText(
					ctx, R.string.toast_save_feed_ok , 
					Toast.LENGTH_SHORT).show();
			break;
		}
    	db.close();
    }

	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		
		menu.add(Menu.CATEGORY_ALTERNATIVE, MENU_SAVEFEED_ID, 0, 
				R.string.menu_view_savefeed)
				.setOnMenuItemClickListener(menuItemClickHandler)
				.setIcon(R.drawable.ic_menu_save);

		menu.add(Menu.CATEGORY_ALTERNATIVE, MENU_XSPF_ID, 0, 
				R.string.menu_view_xspf)
				.setOnMenuItemClickListener(menuItemClickHandler)
				.setIcon(R.drawable.ic_podcast);

		return true;
	}

	private OnMenuItemClickListener menuItemClickHandler = new OnMenuItemClickListener() {
		@Override
		public boolean onMenuItemClick(MenuItem item) {
			if(fi.size()==0) {
				Toast.makeText(ctx, R.string.toast_no_act, Toast.LENGTH_LONG).show();
			} else {
				switch (item.getItemId()) {
				case MENU_SAVEFEED_ID:
					managePrefFeed();
					break;
				case MENU_XSPF_ID:
					mpIntent.putExtra("type", MENU_XSPF_ID);
					activity.startActivity(mpIntent);
					break;
				}
			}
			
			return true;
		}
	};

	private void fillCommonContextMenuItems(IcoCtxMenu menu){
		menu.addItem(res, R.string.diag_act_meta, R.drawable.tag,
				MENUCTX_ITEM_META);
//		menu.addItem(res, R.string.act_url_dialog, R.drawable.url,
//				MENUCTX_ITEM_URL);
		//menu.addItem(res, R.string.act_QR_dialog, R.drawable.qr,
		//		MENUCTX_ITEM_QR);	
	}
	
	private void fillContextMenus() {
		fillCommonContextMenuItems(icoCtxMenu);
		//if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO){
		icoCtxMenu.addItem(res, R.string.diag_act_download, R.drawable.download, MENUCTX_ITEM_DOWN);
		icoCtxMenu.addItem(res, R.string.diag_act_QR, R.drawable.qr,	MENUCTX_ITEM_QR);
		//}
		if (SMethod.isIntentAvailable(ctx,Intent.ACTION_VIEW, "application/x-bittorrent"))
			icoCtxMenu.addItem(res, R.string.diag_act_torrent,
						R.drawable.torrrent, MENUCTX_ITEM_TORRENT);
		
		fillCommonContextMenuItems(icoCtxMenuDir);
	}
	
	private void setCbackCtxMenu(IcoCtxMenu menu) {
		menu.setOnClickListener(new IcoCtxMenu.IconContextMenuOnClickListener() {
			@Override
			public void onClick(int menuId) {
				if (ctxMenuItemPos >= 0) {
					Log.d(LOG_TAG, "onClick() pos:" + ctxMenuItemPos);
					FeedItem feed = fi.get(ctxMenuItemPos);

					switch (menuId) {
					case MENUCTX_ITEM_META:
						removeDialog(DIALOG_META);
						showDialog(DIALOG_META);
						break;
					/*case MENUCTX_ITEM_URL:
						Toast.makeText(ctx, "menu item 2",
								1000).show();
						break;*/
					case MENUCTX_ITEM_QR:
						removeDialog(DIALOG_QR);
						showDialog(DIALOG_QR);
						break;
					case MENUCTX_ITEM_DOWN:
						String downloadUrl = ((FeedItemFile) feed).getDownload();
						if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO){
							startDownload(downloadUrl);
						} else {
							Intent intent = new Intent(getBaseContext(), Downloader.class);
							Messenger messenger = new Messenger(download22handler);
							intent.putExtra("messenger", messenger);
							
							intent.setData(Uri.parse(downloadUrl));
							intent.putExtra("urlpath", downloadUrl);
							startService(intent);
						}
						break;
					case MENUCTX_ITEM_TORRENT:
						String torrent_url = fromQueryUrlToItemrl(((FeedItemFile) feed).getTorrent());
						final Intent i = new Intent(Intent.ACTION_VIEW)
						.addCategory(Intent.CATEGORY_DEFAULT)
						.setData(Uri.parse(torrent_url))
						.setType("application/x-bittorrent");
					    ClipboardManager cb = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
					    cb.setText(torrent_url);
						Toast.makeText(ctx,
								R.string.toast_copy_on_clipboard+
								R.string.toast_add_torrent
								, Toast.LENGTH_LONG)
								.show();
					    startActivity(i);
						break;
					}
				}
			}
		});
	}
	
	private static OnItemLongClickListener gridItemLongClickHandler = new OnItemLongClickListener() {
		@Override
		public boolean onItemLongClick(AdapterView<?> parent, View view,
				int position, long id) {
			Log.i(LOG_TAG, "gridItLongClick");
			ctxMenuItemPos = position;
			if (fi.get(position).getMediaType()
					.equalsIgnoreCase(res.getString(R.string.rss_type_dir)))
				activity.showDialog(CTX_MENU_ID_DIR);
			else
				activity.showDialog(CTX_MENU_ID);

			return true;
		}
	};
	
	@Override
	protected Dialog onCreateDialog(int id) {
		Log.i(LOG_TAG, "onCreateDialog()");
		FeedItem feed = fi.get(ctxMenuItemPos);
		switch (id) {
		case CTX_MENU_ID:
			dialog = icoCtxMenu.createMenu("Menu: " + feed.getTitle(),
					R.drawable.file);
			break;
		case CTX_MENU_ID_DIR:
			dialog = icoCtxMenuDir.createMenu("Menu: " + feed.getTitle(),
					R.drawable.file);
			break;
		case DIALOG_QR:
			dialog = SDialog.showQRDialog(this, fromQueryUrlToItemrl(fi.get(ctxMenuItemPos).getQrcode()));
			break;
		case DIALOG_META:
			dialog = SDialog.showMetaDialog(this, fi.get(ctxMenuItemPos));
			break;
		case DIALOG_VITAMIO_COMPATIBLE:
			dialog = SDialog.vitamioDialog(this, DIALOG_VITAMIO_COMPATIBLE);
			break;
		case DIALOG_VITAMIO_NOTF:
			dialog = SDialog.vitamioDialog(this, DIALOG_VITAMIO_NOTF);
			break;
		default:
			dialog = super.onCreateDialog(id);
			break;
		}

		return dialog;
	}
	
	private String fromQueryUrlToItemrl(String str){
		return str
				.replace("www", "backend")
				.replace("path64","item64")
				.replace("search64","item64");
	}

	private static boolean isLastPop(){
		boolean isLast=true;
		
		if(rssDocs.treeNum() > 1){
			startTask(rssDocs.treePopElement());
			isLast=false;
		}
		
		return isLast;
	}
	
	@Override
    public Object onRetainNonConfigurationInstance() {
		Log.i(LOG_TAG,"onRetainNonConfigurationInstance()");
		HashMap<String, Object> state = new HashMap<String, Object>();
		state.put("grid", fq);
        return state;
    }
	
	@Override  
	public void onBackPressed()  
	{  
		if(isLastPop()) {
			if(RssDoc.getNBackPress()==1) {
				RssReader.setFromState(RssReader.STATE_BACK_VIEWER);
				super.onBackPressed();	
			} else {
				RssDoc.raiseNBackPress();
				Toast.makeText(ctx, R.string.toast_back_preroot, Toast.LENGTH_LONG).show();
			}
		} 
			
	    return;  
	}  
    
    @Override
    protected void onStop() {
    	Log.i(LOG_TAG,"onStop()");
    	super.onStop();
		if (RssReader.getFromState() == RssReader.STATE_RESUME_VIEWER) 
			RssReader.setFromState(RssReader.STATE_INIT_VIEWER);

    	gridView.setAdapter(null);
    	if (gridAdapter != null)
    		gridAdapter.clearData();
		
    	if(task!=null)
    		task.cancel(true);
    }
}
