public void setEpisode(IEpisode argEpisode) {
    mEpisode = argEpisode;

    if (mEpisode.getOffset() > 0 && mEpisode.getDuration() > 0) {
      float progress = (float) mEpisode.getOffset() / mEpisode.getDuration();
      setProgress((int) (progress * RANGE_MAX));
    }
  }
  public void setProgressMs(long progressMs) {
    if (isTouching()) {
      return;
    }

    if (progressMs < 0) {
      Throwable ise = new IllegalStateException("Progress must be positive");
      Log.e("PlayerSeekbar", "Progress must be positive ( " + progressMs + " )", ise);
      return;
    }

    float progress = 0;
    float duration = mEpisode.getDuration();

    if (duration <= 0) {
      Log.d("Warning", "Seekbar state may be invalid");
      return;
    }

    try {
      progress = progressMs / duration * RANGE_MAX;
    } catch (Exception e) {
      e.printStackTrace();
    }
    setProgress((int) progress);
  }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
          Log.d("PlayerSeekbar state", "onStartTrackingTouch");
          validateState();

          FixedRecyclerView.mSeekbarSeeking = true;

          if (mDurationMs < 0) {
            mDurationMs = mEpisode.getDuration();
          }

          Log.d("mPaintSeekInfo", "onStartTracking mPaintSeekInfo => " + mPaintSeekInfo);
          mIsTouching = true;
          mThressholdCounter = cDrawThresshold;
          mStartSeekPosition = seekBar.getProgress();

          long timeMs = mEpisode.getDuration() * seekBar.getProgress() / RANGE_MAX;
          mEpisode.setOffset(null, (long) timeMs);
        }
  public void onStateChange(EpisodeStatus argStatus) {
    validateState();

    mIsPlaying = argStatus.getStatus() == PlayerStatusObservable.STATUS.PLAYING;

    float currentPositionMs =
        argStatus.getPlaybackPositionMs() < 0 ? 0 : argStatus.getPlaybackPositionMs();
    double episodeLenghtMS = (double) mEpisode.getDuration();

    if (episodeLenghtMS < 0 || currentPositionMs > episodeLenghtMS) {
      return;
      // throw new IllegalStateException("Illegal Seekbar State: current position: " +
      // currentPositionMs + ", episode length: " + episodeLenghtMS);
    }

    if (mIsPlaying) {
      float progress = currentPositionMs / mEpisode.getDuration() * RANGE_MAX;
      setProgress((int) progress);
    }
  }
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
          Log.d("PlayerSeekbar state", "onStopTrackingTouch");
          mIsTouching = false;
          mPaintSeekInfo = false;
          Log.d("mPaintSeekInfo", "onStopTracking mPaintSeekInfo => " + mPaintSeekInfo);
          mThressholdCounter = -1;

          validateState();
          long timeMs = mEpisode.getDuration() * seekBar.getProgress() / RANGE_MAX;

          if (mEpisode.equals(MainActivity.sBoundPlayerService.getCurrentItem())) {
            MainActivity.sBoundPlayerService.seek(timeMs);
          } else {
            mEpisode.setOffset(MainActivity.sBoundPlayerService.getContentResolver(), timeMs);
            // FIXME
            // PlayerStatusObservable.updateProgress(MainActivity.sBoundPlayerService, mEpisode);
            setProgressMs(timeMs);
          }

          FixedRecyclerView.mSeekbarSeeking = false;
          invalidate();
        }
 @Override
 public String getPaletteUrl() {
   return mEpisode.getArtwork(getContext());
 }