/*
 * Copyright (C) 2013 Simon Vig Therkildsen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.simonvt.cathode.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
import net.simonvt.cathode.util.DateUtils;

public class TimeStamp extends TextView {

  private long timeInMillis;

  private boolean extended;

  public TimeStamp(Context context) {
    super(context);
  }

  public TimeStamp(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public TimeStamp(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public void setTimeInMillis(long timeInMillis) {
    this.timeInMillis = timeInMillis;

    removeCallbacks(updater);
    updater.run();
  }

  public void setExtended(boolean extended) {
    this.extended = extended;
  }

  private final Runnable updater = new Runnable() {
    @Override public void run() {
      final String timeStamp = DateUtils.millisToString(getContext(), timeInMillis, extended);
      setText(timeStamp);

      final long nextUpdate = DateUtils.timeUntilUpdate(timeInMillis);
      postDelayed(this, nextUpdate);
    }
  };

  @Override protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if (timeInMillis > 0) updater.run();
  }

  @Override protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    removeCallbacks(updater);
  }
}

@@ -670,16 +670,96 @@
 ontext;%0A
+import android.os.Handler;%0Aimport android.os.Looper;%0Aimport android.os.Message;%0A
 import a
@@ -816,16 +816,52 @@
 xtView;%0A
+import java.lang.ref.WeakReference;%0A
 import n
@@ -939,16 +939,60 @@
 View %7B%0A%0A
+  private static final int MSG_UPDATE = 1;%0A%0A
   privat
@@ -1042,16 +1042,78 @@
 ended;%0A%0A
+  private TimeStampHandler handler = new TimeStampHandler();%0A%0A
   public
@@ -1469,49 +1469,23 @@
     
-removeCallbacks(updater);%0A    updater.run
+updateTimestamp
 ();%0A
@@ -1584,86 +1584,33 @@
 ate 
-final Runnable updater = new Runnable() %7B%0A    @Override public void run
+void updateTimestamp
 () %7B%0A
-  
     
@@ -1702,18 +1702,16 @@
 d);%0A    
-  
 setText(
@@ -1727,24 +1727,16 @@
 );%0A%0A    
-  final 
 long nex
@@ -1794,26 +1794,270 @@
     
-  postDelayed(this
+nextUpdate = Math.min(nextUpdate, 1 * DateUtils.HOUR_IN_MILLIS);%0A    handler.removeMessages(MSG_UPDATE);%0A%0A    Message m = handler.obtainMessage(MSG_UPDATE);%0A    m.what = MSG_UPDATE;%0A    m.obj = new WeakReference%3CTimeStamp%3E(this);%0A    handler.sendMessageDelayed(m
 , ne
@@ -2073,16 +2073,9 @@
 ;%0A  
-  %7D%0A  %7D;
+%7D
 %0A%0A  
@@ -2184,22 +2184,40 @@
  0) 
-updater.run();
+%7B%0A      updateTimestamp();%0A    %7D
 %0A  %7D
@@ -2278,67 +2278,540 @@
     
-super.onDetachedFromWindow();%0A    removeCallbacks(updater);
+handler.removeMessages(MSG_UPDATE);%0A    super.onDetachedFromWindow();%0A  %7D%0A%0A  private static class TimeStampHandler extends Handler %7B%0A    public TimeStampHandler() %7B%0A      super(Looper.getMainLooper());%0A    %7D%0A%0A    @Override public void handleMessage(Message msg) %7B%0A      switch (msg.what) %7B%0A        case MSG_UPDATE:%0A          WeakReference%3CTimeStamp%3E ref = (WeakReference%3CTimeStamp%3E) msg.obj;%0A          TimeStamp ts = ref.get();%0A          if (ts != null) %7B%0A            ts.updateTimestamp();%0A          %7D%0A          break;%0A      %7D%0A    %7D
 %0A  %7D

Resolve memory leak on broken devices.