package org.sana.android.media;
import java.io.File;
import java.io.IOException;
import org.sana.R;
import org.sana.android.Constants;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
/**
* Representation of an informative media resource. May be image, video, audio,
* or text. The resource may be targeted towards specific groups by specifying
* the audience.
* <br/>
* See {@link #EducationResourceParser()} for XML specification.
*
* @author Sana Development Team
*/
public class EducationResource implements Parcelable,
Comparable<EducationResource>
{
/**
* An enumeration of accepted target audiences for media
* @author Sana Development Team
*/
public enum Audience{
ALL,
ERROR,
PATIENT,
WORKER;
/**
* Returns the lower case value of <b>Audience.name()</b>
*/
@Override
public String toString(){
return this.name().toLowerCase();
}
}
public static final String TAG = EducationResource.class.getSimpleName();
// xml tags
/** An a list of items. */
public static final String LIST = "mediaList";
/** The media type. */
public static final String ITEM = "educationResource";
/** A unique identifier */
public static final String ID = "id";
/** The version of this resource */
public static final String VERSION = "majorMinorVersion";
/** A title for display. */
public static final String TITLE = "name";
/** The author of the resource */
public static final String AUTHOR = "author";
/** A short but descriptive text about the resource. */
public static final String DESCRIPTION = "description";
/** Informative text in lieu of, or addition to, a media resource. */
public static final String TEXT = "text";
/** The name of a media file. */
public static final String FILENAME = "resource";
/** The remote location to get the media from. */
public static final String DOWNLOAD_URL = "downloadUrl";
/** The media mime type. */
public static final String MIMETYPE = "mimeType";
/** A hash of the resource */
public static final String HASH = "hash";
/** The group this resource is directed towards */
public static final String AUDIENCE = "audience";
/** Default path to look for media resources */
public static final String DEFAULT_MEDIA_PATH = Constants.PATH_EDUCATION;
/** Default root directory on the SD card */
public static final String DEFAULT_MEDIA_ROOT =
Environment.getExternalStorageDirectory().getAbsolutePath();
/** Default name of the XML file holding a list of available resources */
public static final String DEFAULT_MEDIA_XML = "manifest.xml";
public String id = "";
public String name = "";
public String version="";
public String author = "";
public String description = "";
public String text = "";
public String filename = "";
public String downloadUrl = "";
public String hash = "";
public String mimeType = "";
public Audience audience = Audience.ALL;
/**
* A new Media instance with all fields initialized to empty strings and a
* target audience of ALL.
*/
public EducationResource(){}
/**
* A new Media instance read from a Parcel
* @param in the Parcel to read from
*/
public EducationResource(Parcel in){
id = in.readString();
name = in.readString();
author = in.readString();
description = in.readString();
text = in.readString();
filename = in.readString();
downloadUrl = in.readString();
hash = in.readString();
mimeType = in.readString();
audience = Audience.valueOf(in.readString().toUpperCase());
}
/**
* Compares this object to another HelpInfo instance. Comparison order is
* by Title then audience.
*/
@Override
public int compareTo(EducationResource rsrc){
int beforeTitle = compareTitle(rsrc);
if (beforeTitle == 0){
return compareAudience(rsrc);
} else {
return beforeTitle;
}
}
private int compareTitle(EducationResource rsrc){
return this.name.compareToIgnoreCase(rsrc.name);
}
private int compareAudience(EducationResource rsrc){
return this.audience.name().compareToIgnoreCase(rsrc.audience.name());
}
/**
* Checks whether this HelpInfo has a valid resource. This is included to
* facilitate run time checks.
*
* @return True if resource is defined and file exists or if resource is
* not defined and text is not empty;
* @throws IOException If external storage drive is not mounted.
*/
public boolean hasValidResource() {
boolean result = false;
String mount = Environment.getExternalStorageState();
if(!mount.equals(Environment.MEDIA_MOUNTED)){
Log.e(TAG, "Can not open external storage. " + mount);
return false;
}
if(!TextUtils.isEmpty(this.filename)){
File f = new File(EducationResource.DEFAULT_MEDIA_ROOT
+ EducationResource.DEFAULT_MEDIA_PATH +
this.filename);
if(!f.exists()){
// resource not null and file does not exist
this.text = "Resource not available";
} else {
// resource not null and exists
result = true;
}
} else {
// text only
result = (TextUtils.isEmpty(this.text))? false: true;
}
if (!result)
this.audience = Audience.ERROR;
return result;
}
/**
* Generates a Uri for this media file.
* @param root the root path
* @return
*/
public Uri uri(String root){
String mediaPath = root + filename;
File f = new File(mediaPath);
Log.d(TAG, f.getAbsolutePath());
return Uri.fromFile(f);
}
/**
* Generates a Uri for this media file.
* @param root the root path
* @return
*/
public Uri uri(File dir){
File f = new File(dir,filename);
Log.d(TAG, f.getAbsolutePath());
return Uri.fromFile(f);
}
/**
* Formats an input String to a media compatible id
* @param input The String to convert
* @return A String with whitespace and all non-alphanumeric characters
* stripped
*/
public static String toId(String input){
String regex = "[^a-zA-Z0-9]";
String nid = input.replaceAll(regex, "");
Log.d(TAG, " New id: " + nid);
return nid;
}
public static EducationResource error(String attr, String text){
EducationResource err = new EducationResource();
err.text = "XML Error: attr: " + attr + ", value: " + text;
err.filename = null;
return err;
}
/**
* Displays the resource as a text Dialog
*
* @param c
* @param media the help info to display as text
* @return a new help dialog
*/
public static AlertDialog asDialog(Context c, EducationResource media){
AlertDialog.Builder builder = new AlertDialog.Builder(c);
builder.setMessage(media.text).setPositiveButton(
c.getResources().getString(R.string.general_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
return builder.create();
}
/**
* Returns the manifest for education resources.available on the external
* storage device.
*
* @return A file object.
*/
public static File getManifest(){
return new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+Constants.PATH_EDUCATION + Constants.MANIFEST);
}
/**
* Returns the metadata for education resources available on the external
* storage device.
*
* @return A file object.
*/
public static File getMetadata(){
return new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+Constants.PATH_EDUCATION + Constants.METADATA);
}
public static File getDir(){
return new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+Constants.PATH_EDUCATION);
}
/**
* Creates the necessary directories and files on the external drive
*/
public static void intializeDevice(){
String mount = Environment.getExternalStorageState();
Log.d(TAG, "Media stat:" + mount);
if(!mount.equals(Environment.MEDIA_MOUNTED)){
Log.e(TAG, "Can not initialize sdcard education resource dir.");
return;
}
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+Constants.PATH_EDUCATION);
if (f.mkdirs()){
Log.d(TAG, "Created Sana media directories");
} else {
Log.d(TAG, "Sana media directory failed. Already exists:"
+ f.exists());
}
File nm = new File(f, ".nomedia");
try {
if(!nm.exists())
nm.createNewFile();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
/** {@inheritDoc} */
@Override
public int describeContents() {
return 0;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(name);
dest.writeString(author);
dest.writeString(description);
dest.writeString(text);
dest.writeString(filename);
dest.writeString(downloadUrl);
dest.writeString(hash);
dest.writeString(mimeType);
dest.writeString(audience.toString());
}
/** Parcelable.Creator implementation for EducationResource object */
public static final Creator<EducationResource> CREATOR =
new Creator<EducationResource>(){
/** {@inheritDoc} */
@Override
public EducationResource createFromParcel(Parcel source) {
return new EducationResource(source);
}
/** {@inheritDoc} */
@Override
public EducationResource[] newArray(int size) {
EducationResource[] result = new EducationResource[size];
return result;
}};
}