package org.geuz.onelab;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Xml;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

public class ModelList extends Activity {
	
	private ModelArrayAdapter _modelArrayAdapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		_modelArrayAdapter = new ModelArrayAdapter(this);
		try {
			this.getModels();
		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		LinearLayout layout = new LinearLayout(this);
    	layout.setOrientation(LinearLayout.VERTICAL);
    	ListView list = new ListView(this);
    	list.setAdapter(_modelArrayAdapter);
    	list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			public void onItemClick(AdapterView<?> parent, View view, int position,
					long id) {
				Model m = _modelArrayAdapter.getModel(position);
				Intent intent = new Intent(ModelList.this, MainActivity.class);
				intent.putExtra("file", m.getFile().toString());
				intent.putExtra("name", m.getName());
				startActivity(intent);
			}
		});
    	list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id) {
				final Model m = _modelArrayAdapter.getModel(position);
				CharSequence[] actions;
				if(m.getUrl() != null) {
					actions = new CharSequence[2];
					actions[0] = "Open this model";
					actions[1] = "More information";
				}
				else {
					actions = new CharSequence[1];
					actions[0] = "Open this model";
				}
				AlertDialog.Builder builder = new AlertDialog.Builder(parent.getContext());
				builder.setTitle(m.getName());
				builder.setItems(actions, new DialogInterface.OnClickListener() {
				    public void onClick(DialogInterface dialog, int position) {
				    	switch (position) {
						case 1:
							Intent browserIntent = new Intent(Intent.ACTION_VIEW, m.getUrl());
							startActivity(browserIntent);
							break;
						default:
							Intent intent = new Intent(ModelList.this, MainActivity.class);
							intent.putExtra("file", m.getFile().toString());
							intent.putExtra("name", m.getName());
							startActivity(intent);
							break;
						}
				    }
				});
				AlertDialog alert = builder.create();
				alert.show();
				return true;
			}
		});
    	layout.addView(list);
		this.setContentView(layout);
		layout.setPadding(15, 10, 10, 5);
		layout.setBackgroundColor(Color.argb(255, 67, 67, 67));
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuItem loadFile = menu.add(R.string.button_open_file);
		loadFile.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		if(item.getTitle().equals(getString(R.string.button_open_file))) {
			Intent fileBrowserIntent = new Intent();
			fileBrowserIntent.setAction(Intent.ACTION_GET_CONTENT);
			fileBrowserIntent.setType("file/*");
			try {
				startActivityForResult(fileBrowserIntent, 1);
			}
			catch(ActivityNotFoundException e) {
				Toast.makeText(this, "No application found on your device to open the files.", Toast.LENGTH_LONG).show();
			}
		}
		return super.onMenuItemSelected(featureId, item);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode == RESULT_CANCELED) return;
		switch (requestCode) {
		case 1:
			Uri uri = data.getData();
			String[] projection = { MediaStore.Images.Media.DATA };
	        Cursor cursor = managedQuery(uri, projection, null, null, null);
	        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	        cursor.moveToFirst();
			Intent intent = new Intent(ModelList.this, MainActivity.class);
			intent.putExtra("file", cursor.getString(column_index));
			intent.putExtra("name", "None");
			startActivity(intent);
			break;
		}
	}
	
	private void getModels() throws XmlPullParserException, IOException
    {
		File document = this.getFilesDir();
		File files[] = document.listFiles();
		for(int i=0; i<files.length; i++) {
			if(files[i].isDirectory()) { // models are in directory
				File xmlInfos = new File(files[i], "infos.xml");
				if(!xmlInfos.isFile()) continue;
				InputStream in = new FileInputStream(xmlInfos);
				try {
					XmlPullParser parser = Xml.newPullParser();
					parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
					parser.setInput(in, null);
					parser.nextTag();
					parser.require(XmlPullParser.START_TAG, null, "models");
					while (parser.next() != XmlPullParser.END_TAG) {
						if (parser.getEventType() != XmlPullParser.START_TAG) continue;
						String tagName = parser.getName();
						if(tagName.equals("model"))
							readModel(parser, files[i].toString());
						else
							skipTag(parser);
					}
				}
				finally {
					in.close();
				}
			}
		}
    }
	private void readModel(XmlPullParser parser, String dir) throws XmlPullParserException, IOException{
		parser.require(XmlPullParser.START_TAG, null, "model");
		String title = null;
	    String summary = null;
	    String file = null;
	    String bitmap = null;
	    String url = null;
	    while (parser.next() != XmlPullParser.END_TAG) {
	    	if (parser.getEventType() != XmlPullParser.START_TAG) continue;
	    	String name = parser.getName();
	    	if(name.equals("title")) {
	    		if (parser.next() == XmlPullParser.TEXT) {
	    			title = parser.getText();
	    			parser.nextTag();
	    		}
	    	}
	    	else if(name.equals("summary")) {
	    		if (parser.next() == XmlPullParser.TEXT) {
	    			summary = parser.getText();
	    			parser.nextTag();
	    		}
	    	}
	    	else if(name.equals("file")) {
	    		//String relType = parser.getAttributeValue(null, "type"); 
	    		if (parser.next() == XmlPullParser.TEXT) {
	    			file = parser.getText();
	    			parser.nextTag();
	    		}
	    	}
	    	else if(name.equals("preview")) {
	    		if (parser.next() == XmlPullParser.TEXT) {
	    			bitmap = parser.getText();
	    			parser.nextTag();
	    		}
	    	}
	    	else if(name.equals("url")) {
	    		if (parser.next() == XmlPullParser.TEXT) {
	    			url = parser.getText();
	    			parser.nextTag();
	    		}
	    	}
	    	else {
	    		skipTag(parser);
	    	}
	    }
	    if(title == null || file == null) return;
	    Model newModel = new Model(title, summary, new File(dir+"/"+file));
	    if(bitmap != null) newModel.setBitmap(new File(dir+"/"+bitmap));
	    if(url != null) newModel.setUrl(Uri.parse(url));
	    _modelArrayAdapter.add(newModel);
	}
	private void skipTag(XmlPullParser parser) throws XmlPullParserException, IOException {
	    if (parser.getEventType() != XmlPullParser.START_TAG) {
	        throw new IllegalStateException();
	    }
	    int depth = 1;
	    while (depth != 0) {
	        switch (parser.next()) {
	        case XmlPullParser.END_TAG:
	            depth--;
	            break;
	        case XmlPullParser.START_TAG:
	            depth++;
	            break;
	        }
	    }
	 }
}
