package com.teamluper.luper;
import android.media.MediaPlayer;
import android.os.Looper;
import android.view.View;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.util.ArrayList;
public class AudioFile {
private SQLiteDataSource dataSource;
private long id;
private long ownerUserID;
private String clientFilePath;
private String serverFilePath;
private String fileFormat;
private double bitrate;
private double durationMS;
private boolean isReadyOnClient;
private boolean isReadyOnServer;
private long renderSequenceID;
private boolean isDirty;
// references to any views depending on this data, so we can invalidate them automatically on set___ calls.
public ArrayList<View> associatedViews = null;
// NOTE: DO NOT CALL THIS CONSTRUCTOR DIRECTLY unless in a cursorToAudioFile method.
// instead, use SQLiteDataSource.createAudioFile()!
public AudioFile(SQLiteDataSource dataSource, long id, long ownerUserID,
String clientFilePath, String serverFilePath,
String fileFormat, double bitrate, double durationMS,
boolean isReadyOnClient, boolean isReadyOnServer,
long renderSequenceID, boolean isDirty) {
this.dataSource = dataSource;
this.id = id;
this.ownerUserID = ownerUserID;
this.clientFilePath = clientFilePath;
this.serverFilePath = serverFilePath;
this.fileFormat = fileFormat;
this.bitrate = bitrate;
this.durationMS = durationMS;
this.isReadyOnClient = isReadyOnClient;
this.isReadyOnServer = isReadyOnServer;
this.renderSequenceID = renderSequenceID;
this.isDirty = isDirty;
this.associatedViews = new ArrayList<View>();
}
public void addAssociatedView(View view) {
this.associatedViews.add(view);
}
public void removeAssociatedView(View view) {
this.associatedViews.remove(view);
}
public ArrayList<View> getAssociatedViews() {
return this.associatedViews;
}
public void invalidateAssociatedViews() {
for(View v : this.associatedViews) {
v.requestLayout();
v.refreshDrawableState();
if (Looper.myLooper() != null && Looper.myLooper() == Looper.getMainLooper()) {
// we're in the main-thread / UI Thread.
v.invalidate();
} else {
// we're in a background thread.
v.postInvalidate();
}
}
}
public long getId() { return id; }
public void setId(long id) {
long oldId = this.id;
this.id = id;
dataSource.updateLong("Files", oldId, "_id", id);
invalidateAssociatedViews();
this.isDirty = true;
}
public long getOwnerUserID() { return ownerUserID; }
public void setOwnerUserID(long ownerUserID) {
this.ownerUserID = ownerUserID;
dataSource.updateLong("Files", this.id, "ownerUserID", ownerUserID);
invalidateAssociatedViews();
this.isDirty = true;
}
public String getClientFilePath() { return clientFilePath; }
public void setClientFilePath(String clientFilePath) {
this.clientFilePath = clientFilePath;
dataSource.updateString("Files", this.id, "clientFilePath", clientFilePath);
invalidateAssociatedViews();
this.isDirty = true;
}
public String getServerFilePath() { return serverFilePath; }
public void setServerFilePath(String serverFilePath) {
this.serverFilePath = serverFilePath;
dataSource.updateString("Files", this.id, "serverFilePath", serverFilePath);
invalidateAssociatedViews();
this.isDirty = true;
}
public String getFileFormat() { return fileFormat; }
public void setFileFormat(String fileFormat) {
this.fileFormat = fileFormat;
dataSource.updateString("Files", this.id, "fileFormat", fileFormat);
invalidateAssociatedViews();
this.isDirty = true;
}
public double getBitrate() { return bitrate; }
public void setBitrate(double bitrate) {
this.bitrate = bitrate;
dataSource.updateDouble("Files", this.id, "bitrate", bitrate);
invalidateAssociatedViews();
this.isDirty = true;
}
public double getDurationMS() { return durationMS; }
public void setDurationMS(double durationMS) {
this.durationMS = durationMS;
dataSource.updateDouble("Files", this.id, "durationMS", durationMS);
invalidateAssociatedViews();
this.isDirty = true;
}
public boolean isReadyOnClient() { return isReadyOnClient; }
public void setReadyOnClient(boolean isReadyOnClient) {
this.isReadyOnClient = isReadyOnClient;
dataSource.updateInt("Files", this.id, "isReadyOnClient", (isReadyOnClient ? 1 : 0));
invalidateAssociatedViews();
this.isDirty = true;
}
public boolean isReadyOnServer() { return isReadyOnServer; }
public void setReadyOnServer(boolean isReadyOnServer) {
this.isReadyOnServer = isReadyOnServer;
dataSource.updateInt("Files", this.id, "isReadyOnServer", (isReadyOnServer ? 1 : 0));
invalidateAssociatedViews();
this.isDirty = true;
}
public long getRenderSequenceID() { return renderSequenceID; }
public void setRenderSequenceID(long renderSequenceID) {
this.renderSequenceID = renderSequenceID;
dataSource.updateLong("Files", this.id, "renderSequenceID", renderSequenceID);
invalidateAssociatedViews();
this.isDirty = true;
}
public boolean isDirty() { return isDirty; }
public void setDirty(boolean isDirty) {
this.isDirty = isDirty;
dataSource.updateInt("Files", this.id, "isDirty", (isDirty ? 1 : 0));
invalidateAssociatedViews();
}
public void loadAudio() {
// TODO doesn't do anything, find out where to use it or remove it
//String fp = this.getClientFilePath();
}
//Extra length method using mediaplayer which oddly uses an integer for the duration
public int calcDuration() { //FIXME update database with current duration , refactor
try {
MediaPlayer mp = new MediaPlayer();
FileInputStream fs;
FileDescriptor fd;
fs = new FileInputStream(this.getClientFilePath());
fd = fs.getFD();
mp.setDataSource(fd);
mp.prepare();
int length = mp.getDuration();
mp.release();
return length;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}