/FileExtraction/Java_unseen/Kegbot_kegbot-android/kegtab/src/main/java/org/kegbot/app/EventListFragment.java
/*
 * Copyright 2003-2020 The Kegbot Project contributors <info@kegbot.org>
 *
 * This file is part of the Kegtab package from the Kegbot project. For
 * more information on Kegtab or Kegbot, see <http://kegbot.org/>.
 *
 * Kegtab is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 2.
 *
 * Kegtab 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with Kegtab. If not, see <http://www.gnu.org/licenses/>.
 */
package org.kegbot.app;

import android.app.Activity;
import android.app.ListFragment;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Html;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.squareup.otto.Subscribe;

import org.kegbot.app.config.AppConfiguration;
import org.kegbot.app.event.SystemEventListUpdateEvent;
import org.kegbot.app.util.ImageDownloader;
import org.kegbot.app.util.Units;
import org.kegbot.core.KegbotCore;
import org.kegbot.core.SyncManager;
import org.kegbot.proto.Models;
import org.kegbot.proto.Models.Drink;
import org.kegbot.proto.Models.SystemEvent;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Lists recent events.
 */
public class EventListFragment extends ListFragment {

  private static final String TAG = EventListFragment.class.getSimpleName();

  /** Maximum number of events to show/retain. */
  private static final int MAX_EVENTS = 20;
  private static final long REFRESH_INTERVAL_MILLIS = TimeUnit.MINUTES.toMillis(1);

  private View mView;
  private ArrayAdapter<SystemEvent> mAdapter;
  private KegbotCore mCore;
  private ImageDownloader mImageDownloader;
  private final Handler mHandler = new Handler(Looper.getMainLooper());
  private final List<SystemEvent> mCachedEvents = Lists.newArrayList();

  /** Refreshes event timestamps by invalidating all ListView children periodically. */
  private final Runnable mTimeUpdateRunnable = new Runnable() {
    @Override
    public void run() {
      ListView v = getListView();
      if (v != null) {
        v.invalidateViews();
      }
      mHandler.postDelayed(this, REFRESH_INTERVAL_MILLIS);
    }
  };

  /**
   *
   */
  private class EventListArrayAdapter extends ArrayAdapter<SystemEvent> {

    private EventListArrayAdapter(Context context, int resource, int textViewResourceId) {
      super(context, resource, textViewResourceId);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      final View view = super.getView(position, convertView, parent);
      final SystemEvent eventDetail = getItem(position);
      try {
        formatEvent(eventDetail, view);
      } catch (Throwable e) {
        Log.wtf(TAG, "UNCAUGHT EXCEPTION", e);
      }
      return view;
    }

    private void formatEvent(SystemEvent event, View view) {
      // Common: image.
      final ImageView icon = (ImageView) view.findViewById(R.id.eventIcon);
      icon.setVisibility(View.GONE);
      if (event.hasImage()) {
        final String imageUrl = event.getImage().getThumbnailUrl();
        if (!Strings.isNullOrEmpty(imageUrl)) {
          icon.setVisibility(View.VISIBLE);
          icon.setImageBitmap(null);

          // Default to unknown drinker, may be immediately replaced by downloader.
          icon.setBackgroundResource(R.drawable.unknown_drinker);
          mImageDownloader.download(imageUrl, icon);
        }
      }

      final String eventTextContent;
      final String userNameString = getUsernameForEvent(event);
      if (userNameString != null) {
        eventTextContent = "<b>" + userNameString + "</b> " + getTitle(event);
      } else {
        eventTextContent = getTitle(event);
      }

      final TextView eventText = (TextView) view.findViewById(R.id.eventText);
      eventText.setText(Html.fromHtml(eventTextContent));

      // Date and time.
      TextView dateView = (TextView) view.findViewById(R.id.eventDate);
      String isoTime = event.getTime();
      try {
        long time = org.kegbot.app.util.DateUtils.dateFromIso8601String(isoTime);

        CharSequence relTime = DateUtils.getRelativeDateTimeString(getContext(), time, 60 * 1000,
            7 * 24 * 60 * 60 * 100, 0);
        dateView.setText(relTime);
        dateView.setVisibility(View.VISIBLE);
      } catch (IllegalArgumentException e) {
        dateView.setVisibility(View.GONE);
      }

    }

    private String getTitle(SystemEvent eventDetail) {
      final String kind = eventDetail.getKind();
      final Drink drink = eventDetail.getDrink();
      String result;

      if ("keg_ended".equals(kind)) {
        result = "ended";
      } else if ("keg_tapped".equals(kind)) {
        result = "tapped";
      } else if ("drink_poured".equals(kind)) {
        final AppConfiguration appConfig = KegbotCore.getInstance(getContext()).getConfiguration();
        Pair<String, String> qty = Units.localize(appConfig, drink.getVolumeMl());
        result = String.format("poured %s %s", qty.first, qty.second);
      } else if ("session_joined".equals(kind)) {
        result = "started drinking";
      } else if ("session_started".equals(kind)) {
        result = "started a new session";
      } else {
        result = "Unknown event";
      }
      return result;
    }

    private String getUsernameForEvent(SystemEvent eventDetail) {
      final String userName;
      if (!eventDetail.hasUser()) {
        userName = "a guest";
      } else {
        final Models.User user = eventDetail.getUser();
        if (user.hasDisplayName()) {
          userName = user.getDisplayName();
        } else {
          userName = user.getUsername();
        }
      }

      final String kind = eventDetail.getKind();
      if ("drink_poured".equals(kind)) {
        return userName;
      } else if ("session_joined".equals(kind)) {
        return userName;
      } else if ("session_started".equals(kind)) {
        return userName;
      } else if ("keg_ended".equals(kind) || "keg_tapped".equals(kind)) {
        if (eventDetail.hasKeg()) {
          return "Keg " + eventDetail.getKeg().getId();
        }
      }

      return null;
    }
  }

  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    mImageDownloader = KegbotCore.getInstance(activity).getImageDownloader();
  }

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mAdapter = new EventListArrayAdapter(getActivity(), R.layout.event_list_item, R.id.eventText);

    AnimationSet set = new AnimationSet(true);

    Animation animation = new AlphaAnimation(0.0f, 1.0f);
    animation.setDuration(300);
    set.addAnimation(animation);
    animation = new TranslateAnimation(
        Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
        Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f
    );
    animation.setDuration(300);
    set.addAnimation(animation);

    LayoutAnimationController controller = new LayoutAnimationController(set, 0.3f);
    getListView().setLayoutAnimation(controller);
    setListAdapter(mAdapter);
  }

  @Override
  public void onResume() {
    super.onResume();
    mHandler.postDelayed(mTimeUpdateRunnable, REFRESH_INTERVAL_MILLIS);
    mCore = KegbotCore.getInstance(getActivity());
    mCore.getBus().register(this);
  }

  @Override
  public void onPause() {
    mCore.getBus().unregister(this);
    mHandler.removeCallbacks(mTimeUpdateRunnable);
    super.onPause();
  }

  @Subscribe
  public void onEventListUpdate(SystemEventListUpdateEvent event) {
    List<SystemEvent> newEvents = event.getEvents();
    if (!newEvents.isEmpty()) {
      Log.d(TAG, "Events updated: " + newEvents.size());
      for (SystemEvent e : newEvents) {
        if (!mCachedEvents.contains(e)) {
          mCachedEvents.add(e);
        }
      }

      Collections.sort(mCachedEvents, SyncManager.EVENTS_DESCENDING);
      while (mCachedEvents.size() > MAX_EVENTS) {
        mCachedEvents.remove(mCachedEvents.size() - 1);
      }
      mAdapter.clear();
      mAdapter.addAll(mCachedEvents);
    }

    if (mView != null) {
      if (mCachedEvents.isEmpty()) {
        mView.setVisibility(View.GONE);
      } else {
        mView.setVisibility(View.VISIBLE);
      }
    }
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mView = inflater.inflate(R.layout.event_list_fragment_layout, container, false);
    return mView;
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

}
