blob: cd41a7d687e22bd6e9ced6f45aaf6c95d53e1b72 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.android.apps.syncslides.db;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.joda.time.DateTime;
import org.joda.time.Period;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import io.v.android.apps.syncslides.R;
import io.v.android.apps.syncslides.model.Deck;
import io.v.android.apps.syncslides.model.DeckFactory;
import io.v.android.apps.syncslides.model.Listener;
import io.v.android.apps.syncslides.model.Question;
import io.v.android.apps.syncslides.model.Slide;
/**
* A fake implementation of DB for manual testing purposes.
*/
public class FakeDB implements DB {
private static final int[] SLIDEDRAWABLES = new int[]{
R.drawable.slide1_thumb,
R.drawable.slide2_thumb,
R.drawable.slide3_thumb,
R.drawable.slide4_thumb,
R.drawable.slide5_thumb,
R.drawable.slide6_thumb,
R.drawable.slide7_thumb,
R.drawable.slide8_thumb,
R.drawable.slide9_thumb,
R.drawable.slide10_thumb,
R.drawable.slide11_thumb
};
private final String[] SLIDENOTES = {
"This is the teaser slide. It should be memorable and descriptive of what your " +
"company is trying to do", "",
"The bigger the pain, the better",
"How do you solve this problem? How is it better or different from existing solutions?",
"Demo the product", "", "[REDACTED]",
"They may have tractor traction, but we still have the competitive advantage",
"I'm not a businessman. I'm a business, man", "There is no 'i' on this slide",
"Sqrt(all evil)"};
private static final String TAG = "FakeDB";
private static final int[] DECKTHUMBS = {
R.drawable.thumb_deck1,
R.drawable.thumb_deck2,
R.drawable.thumb_deck3
};
private static final String[] DECKTITLES = {"deck 1", "deck 2", "deck 3"};
private final Handler mHandler;
private final FakeDeckList mDecks = new FakeDeckList();
private final Map<String, FakeSlideList> mSlides = new HashMap();
private List<CurrentSlideListener> mCurrentSlideListeners;
private Thread mCurrentSlideWatcher;
private final List<Question> mQuestions;
private final List<QuestionListener> mQuestionListeners;
private Thread mQuestionWatcher;
public FakeDB(Context context) {
Slide[] slides = new Slide[SLIDEDRAWABLES.length];
for (int i = 0; i < slides.length; ++i) {
slides[i] = new FakeSlide(
BitmapFactory.decodeResource(context.getResources(), SLIDEDRAWABLES[i]),
SLIDENOTES[i]);
}
mHandler = new Handler(Looper.getMainLooper());
for (int i = 0; i < DECKTHUMBS.length; ++i) {
mDecks.add(DeckFactory.Singleton.get(context).make(
DECKTITLES[i], DECKTHUMBS[i], i));
mSlides.put(String.valueOf(i), new FakeSlideList(slides));
}
mCurrentSlideListeners = Lists.newArrayList();
mCurrentSlideWatcher = new Thread(new Runnable() {
@Override
public void run() {
watchCurrentSlide();
}
});
mCurrentSlideWatcher.start();
mQuestions = Lists.newArrayList();
Random random = new Random();
for (int i = 0; i < 5; i++) {
Question question = new Question(
"question" + i,
"Questioner",
"#" + i,
DateTime.now().minus(Period.minutes(random.nextInt(5))));
mQuestions.add(question);
}
mQuestionListeners = Lists.newArrayList();
mQuestionWatcher = new Thread(new Runnable() {
@Override
public void run() {
watchQuestions();
}
});
mQuestionWatcher.start();
}
private static class FakeSlide implements Slide {
private final String mSlideNotes;
private final Bitmap mSlideImage;
FakeSlide(Bitmap slideImage, String slideNotes) {
mSlideImage = slideImage;
mSlideNotes = slideNotes;
}
@Override
public Bitmap getImage() {
return mSlideImage;
}
@Override
public String getNotes() {
return mSlideNotes;
}
}
private static class FakeDeckList implements DBList<Deck> {
private final List<Deck> mDecks = new ArrayList();
private Listener mListener;
@Override
public int getItemCount() {
return mDecks.size();
}
@Override
public Deck get(int i) {
return mDecks.get(i);
}
@Override
public void setListener(Listener listener) {
mListener = listener;
}
@Override
public void discard() {
// Nothing to do.
}
private void add(Deck deck) {
mDecks.add(deck);
if (mListener != null) {
mListener.notifyItemInserted(mDecks.size() - 1);
}
}
private void delete(String deckId) {
for (int i = 0; i < mDecks.size(); ++i) {
if (mDecks.get(i).getId().equals(deckId)) {
mDecks.remove(i);
if (mListener != null) {
mListener.notifyItemRemoved(i);
}
return;
}
}
}
}
private static class FakeSlideList implements DBList<Slide> {
private final List<Slide> mSlides;
private FakeSlideList(Slide[] slides) {
// Slides don't currently change, so store them in the ImmutableList.
mSlides = ImmutableList.<Slide>copyOf(slides);
}
@Override
public int getItemCount() {
return mSlides.size();
}
@Override
public Slide get(int i) {
return mSlides.get(i);
}
private List<Slide> getSlides() {
return mSlides;
}
@Override
public void setListener(Listener listener) {
}
@Override
public void discard() {
}
}
@Override
public void init(Activity activity) {
// Nothing to do.
}
@Override
public void askQuestion(String deckId, String presentationId,
String firstName, String lastName) {
// Nothing to do.
}
@Override
public DBList<Deck> getDecks() {
return mDecks;
}
@Override
public DBList<Slide> getSlides(String deckId) {
return mSlides.get(deckId);
}
public void createPresentation(String deckId, final Callback<CreatePresentationResult> callback) {
mHandler.post(new Runnable() {
@Override
public void run() {
callback.done(new CreatePresentationResult("fakePresentationId", "sgname"));
}
});
}
@Override
public void joinPresentation(String syncgroupName, final Callback<Void> callback) {
mHandler.post(new Runnable() {
@Override
public void run() {
callback.done(null);
}
});
}
@Override
public void setCurrentSlide(String deckId, String presentationId, int slideNum) {
}
@Override
public void addCurrentSlideListener(String deckId, String presentationId,
CurrentSlideListener listener) {
mCurrentSlideListeners.add(listener);
// TODO(kash): It would be better to fire off a notification of the current
// slide right away. That requires storing the current slide in some
// place that is accessible to the UI thread. Too much work for now.
}
@Override
public void removeCurrentSlideListener(String deckId, String presentationId,
CurrentSlideListener listener) {
mCurrentSlideListeners.remove(listener);
}
@Override
public void setQuestionListener(String deckId, String presentationId, QuestionListener listener) {
mQuestionListeners.add(listener);
}
@Override
public void removeQuestionListener(String deckId, String presentationId, QuestionListener listener) {
mQuestionListeners.remove(listener);
}
@Override
public void getSlides(String deckId, final Callback<List<Slide>> callback) {
FakeSlideList list = mSlides.get(deckId);
final List<Slide> slides = list == null ? null : list.getSlides();
// Run the callback asynchronously on the UI thread.
mHandler.post(new Runnable() {
@Override
public void run() {
callback.done(slides);
}
});
}
@Override
public void importDeck(Deck deck, Slide[] slides) {
mDecks.add(deck);
mSlides.put(deck.getId(), new FakeSlideList(slides));
}
@Override
public void importDeck(final Deck deck,
final Slide[] slides,
final Callback<Void> callback) {
new Thread() {
@Override
public void run() {
importDeck(deck, slides);
if (callback != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
callback.done(null);
}
});
}
}
}.start();
}
@Override
public Deck getDeck(String deckId) {
for (int i = 0; i < mDecks.getItemCount(); i++) {
Deck result = mDecks.get(i);
if (result.getId().equals(deckId)) {
return result;
}
}
return null;
}
@Override
public void deleteDeck(String deckId) {
mDecks.delete(deckId);
}
@Override
public void deleteDeck(final String deckId, final Callback<Void> callback) {
new Thread() {
@Override
public void run() {
deleteDeck(deckId);
if (callback != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
callback.done(null);
}
});
}
}
}.start();
}
private void watchCurrentSlide() {
try {
int currentSlide = 0;
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
// TODO(spetrovic): This assumes all decks have the same # of slides. Fix it.
currentSlide = (currentSlide + 1) % SLIDEDRAWABLES.length;
final int finalCurrentSlide = currentSlide;
mHandler.post(new Runnable() {
@Override
public void run() {
for (CurrentSlideListener listener : mCurrentSlideListeners) {
listener.onChange(finalCurrentSlide);
}
}
});
}
} catch (InterruptedException e) {
Log.e(TAG, "Current Slide Watcher interrupted " + e);
}
}
private void watchQuestions() {
try {
Random random = new Random();
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
Collections.shuffle(mQuestions);
int numQuestions = random.nextInt(mQuestions.size());
final List<Question> questions = mQuestions.subList(0, numQuestions);
mHandler.post(new Runnable() {
@Override
public void run() {
for (QuestionListener listener : mQuestionListeners) {
listener.onChange(questions);
}
}
});
}
} catch (InterruptedException e) {
Log.e(TAG, "Question Watcher interrupted " + e);
}
}
}