/*******************************************************************************
 * This file is part of Zandy.
 * 
 * Zandy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Zandy is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with Zandy.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package com.gimranov.zandy.app;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.gimranov.zandy.app.data.Creator;
import com.gimranov.zandy.app.data.Database;
import com.gimranov.zandy.app.data.Item;
import com.gimranov.zandy.app.task.APIRequest;
import com.gimranov.zandy.app.task.ZoteroAPITask;

/**
 * This Activity handles displaying and editing creators. It works almost the same as
 * ItemDataActivity and TagActivity, using a simple ArrayAdapter on Bundles with the creator info.
 * 
 * This currently operates by showing the creators for a given item; it could be
 * modified some day to show all creators in the database (when they come to be saved
 * that way).
 * 
 * @author ajlyon
 *
 */
public class CreatorActivity extends ListActivity {

	private static final String TAG = CreatorActivity.class.getSimpleName();
	
	static final int DIALOG_CREATOR = 3;
	static final int DIALOG_CONFIRM_NAVIGATE = 4;	
	static final int DIALOG_CONFIRM_DELETE = 5;	
	
	public Item item;
	
	private Database db;

	/**
	 * For API <= 7, to pass bundles to activities
	 */
	private Bundle b = new Bundle();
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                
        db = new Database(this);
        
        /* Get the incoming data from the calling activity */
        String itemKey = getIntent().getStringExtra("com.gimranov.zandy.app.itemKey");
        Item item = Item.load(itemKey, db);
        this.item = item;
        
        this.setTitle("Creators for "+item.getTitle());
        
        ArrayList<Bundle> rows = item.creatorsToBundleArray();
        
        /* 
         * We use the standard ArrayAdapter, passing in our data as a Bundle.
         * Since it's no longer a simple TextView, we need to override getView, but
         * we can do that anonymously.
         */
        setListAdapter(new ArrayAdapter<Bundle>(this, R.layout.list_data, rows) {
        	@Override
        	public View getView(int position, View convertView, ViewGroup parent) {
        		View row;
        		
                // We are reusing views, but we need to initialize it if null
        		if (null == convertView) {
                    LayoutInflater inflater = getLayoutInflater();
        			row = inflater.inflate(R.layout.list_data, null);
        		} else {
        			row = convertView;
        		}
         
        		/* Our layout has just two fields */
        		TextView tvLabel = (TextView) row.findViewById(R.id.data_label);
        		TextView tvContent = (TextView) row.findViewById(R.id.data_content);
        		
        		tvLabel.setText(Item.localizedStringForString(
        				getItem(position).getString("creatorType")));
        		tvContent.setText(getItem(position).getString("name"));
         
        		return row;
        	}
        });
        
        ListView lv = getListView();
        lv.setTextFilterEnabled(true);
        lv.setOnItemClickListener(new OnItemClickListener() {
        	// Warning here because Eclipse can't tell whether my ArrayAdapter is
        	// being used with the correct parametrization.
        	@SuppressWarnings("unchecked")
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        		// If we have a click on an entry, do something...
        		ArrayAdapter<Bundle> adapter = (ArrayAdapter<Bundle>) parent.getAdapter();
        		Bundle row = adapter.getItem(position);
        		
/* TODO Rework this logic to open an ItemActivity showing items with this creator
        		if (row.getString("label").equals("url")) {
        			row.putString("url", row.getString("content"));
        			removeDialog(DIALOG_CONFIRM_NAVIGATE);
        			showDialog(DIALOG_CONFIRM_NAVIGATE, row);
        			return;
        		}
        		
        		if (row.getString("label").equals("DOI")) {
        			String url = "https://doi.org/"+Uri.encode(row.getString("content"));
        			row.putString("url", url);
        			removeDialog(DIALOG_CONFIRM_NAVIGATE);
        			showDialog(DIALOG_CONFIRM_NAVIGATE, row);
        			return;
        		}
 */       		
				Toast.makeText(getApplicationContext(), row.getString("name"), 
        				Toast.LENGTH_SHORT).show();
        	}
        });
        
        /*
         * On long click, we bring up an edit dialog.
         */
        lv.setOnItemLongClickListener(new OnItemLongClickListener() {
        	/*
        	 * Same annotation as in onItemClick(..), above.
        	 */
        	@SuppressWarnings("unchecked")
			public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
     			// If we have a long click on an entry, show an editor
        		ArrayAdapter<Bundle> adapter = (ArrayAdapter<Bundle>) parent.getAdapter();
        		Bundle row = adapter.getItem(position);
        		CreatorActivity.this.b = row;
    			removeDialog(DIALOG_CREATOR);
        		showDialog(DIALOG_CREATOR);
        		return true;
          }
        });

    }

    @Override
    public void onDestroy() {
    	if (db != null) db.close();
    	super.onDestroy();
    }
    
    @Override
    public void onResume() {
    	if (db == null) db = new Database(this);
    	super.onResume();
    }
    
	protected Dialog onCreateDialog(int id) {
		final String creatorType = b.getString("creatorType");
		final int creatorPosition = b.getInt("position");
		
		String name = b.getString("name");
		String firstName = b.getString("firstName");
		String lastName = b.getString("lastName");
		
		switch (id) {
		/* Editor for a creator
		 */
		case DIALOG_CREATOR:
			AlertDialog.Builder builder;
			AlertDialog dialog;

			LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
			final View layout = inflater.inflate(R.layout.creator_dialog,
			                              (ViewGroup) findViewById(R.id.layout_root));

			TextView textName = (TextView) layout.findViewById(R.id.creator_name);
			textName.setText(name);
			TextView textFN = (TextView) layout.findViewById(R.id.creator_firstName);
			textFN.setText(firstName);
			TextView textLN = (TextView) layout.findViewById(R.id.creator_lastName);
			textLN.setText(lastName);

			CheckBox mode = (CheckBox) layout.findViewById(R.id.creator_mode);
			mode.setChecked((firstName == null || firstName.equals("")) 
							&& (lastName == null || lastName.equals(""))
							&& (lastName != null && !name.equals("")));
			
			// Set up the adapter to get creator types
			String[] types = Item.localizedCreatorTypesForItemType(item.getType());
						
			// what position are we?
			int arrPosition = 0;
			String localType = "";
			if (creatorType != null) {
				localType = Item.localizedStringForString(creatorType);
			} else {
				// We default to the first possibility when none specified
				localType = Item.localizedStringForString(
										Item.creatorTypesForItemType(item.getType())[0]);
			}
			for (int i = 0; i < types.length; i++) {
				if (types[i].equals(localType)) {
					arrPosition = i;
					break;
				}
			}

			ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
							android.R.layout.simple_spinner_item, types);
		    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			
			Spinner spinner = (Spinner) layout.findViewById(R.id.creator_type);
			spinner.setAdapter(adapter);

			spinner.setSelection(arrPosition);
			builder = new AlertDialog.Builder(this);
			builder.setView(layout);
			builder.setPositiveButton(getResources().getString(R.string.ok), new OnClickListener(){
    	        @SuppressWarnings("unchecked")
				public void onClick(DialogInterface dialog, int whichButton) {
    	        	Creator c;
    				TextView textName = (TextView) layout.findViewById(R.id.creator_name);
    				TextView textFN = (TextView) layout.findViewById(R.id.creator_firstName);
    				TextView textLN = (TextView) layout.findViewById(R.id.creator_lastName);
    				Spinner spinner = (Spinner) layout.findViewById(R.id.creator_type);
    				CheckBox mode = (CheckBox) layout.findViewById(R.id.creator_mode);
    				
    				String selected = (String) spinner.getSelectedItem();
    				// Set up the adapter to get creator types
    				String[] types = Item.localizedCreatorTypesForItemType(item.getType());
    				
    				// what position are we?
    				int typePos = 0;
    				for (int i = 0; i < types.length; i++) {
    					if (types[i].equals(selected)) {
    						typePos = i;
    						break;
    					}
    				}
    				
    				String realType = Item.creatorTypesForItemType(item.getType())[typePos];

    				if (mode.isChecked())
    					c = new Creator(realType, textName.getText().toString(), true);
    				else
    					c = new Creator(realType, textFN.getText().toString(), textLN.getText().toString());
    	            
    	            Item.setCreator(item.getKey(), c, creatorPosition, db);
    	            item = Item.load(item.getKey(), db);
    	            ArrayAdapter<Bundle> la = (ArrayAdapter<Bundle>) getListAdapter();
    	            la.clear();
    	            for (Bundle b : item.creatorsToBundleArray()) {
    	            	la.add(b);
    	            }
    	            la.notifyDataSetChanged();
    	        }
			});
			
			builder.setNeutralButton(getResources().getString(R.string.cancel), new OnClickListener(){
				public void onClick(DialogInterface dialog, int whichButton) {
    	        	// do nothing
    	        }
			});

			builder.setNegativeButton(getResources().getString(R.string.menu_delete), new OnClickListener(){
				@SuppressWarnings("unchecked")
				public void onClick(DialogInterface dialog, int whichButton) {
    	            Item.setCreator(item.getKey(), null, creatorPosition, db);
    	            item = Item.load(item.getKey(), db);
    	            ArrayAdapter<Bundle> la = (ArrayAdapter<Bundle>) getListAdapter();
    	            la.clear();
    	            for (Bundle b : item.creatorsToBundleArray()) {
    	            	la.add(b);
    	            }
    	            la.notifyDataSetChanged();
    	        }
			});
			
			dialog = builder.create();
			return dialog;
			
		case DIALOG_CONFIRM_NAVIGATE:
/*			dialog = new AlertDialog.Builder(this)
		    	    .setTitle("View this online?")
		    	    .setPositiveButton("View", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
		        			// The behavior for invalid URIs might be nasty, but
		        			// we'll cross that bridge if we come to it.
		        			Uri uri = Uri.parse(content);
		        			startActivity(new Intent(Intent.ACTION_VIEW)
		        							.setData(uri));
		    	        }
		    	    }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
		    	        public void onClick(DialogInterface dialog, int whichButton) {
		    	        	// do nothing
		    	        }
		    	    }).create();
			return dialog;*/
			return null;
		default:
			Log.e(TAG, "Invalid dialog requested");
			return null;
		}
	}
               
    /*
     * I've been just copying-and-pasting the options menu code from activity to activity.
     * It needs to be reworked for some of these activities.
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.zotero_menu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.do_sync:
        	if (!ServerCredentials.check(getApplicationContext())) {
            	Toast.makeText(getApplicationContext(), getResources().getString(R.string.sync_log_in_first), 
        				Toast.LENGTH_SHORT).show();
            	return true;
        	}
        	Log.d(TAG, "Preparing sync requests, starting with present item");
        	new ZoteroAPITask(getBaseContext()).execute(APIRequest.update(this.item));
        	Toast.makeText(getApplicationContext(), getResources().getString(R.string.sync_started), 
    				Toast.LENGTH_SHORT).show();
        	
        	return true;
        case R.id.do_new:
    		Bundle row = new Bundle();
    		row.putInt("position", -1);
    		row.putString("itemKey", this.item.getKey());
			removeDialog(DIALOG_CREATOR);
			this.b = row;
    		showDialog(DIALOG_CREATOR);
            return true;
        case R.id.do_prefs:
            startActivity(new Intent(this, SettingsActivity.class));
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}
