public void onDraw(Canvas canvas, int height, int width) {
    int offsetHorizontal = Math.round(mTimedOffsetHorizontal);

    mImageSkyNight.onDraw(canvas, height, width, mOffsetVertical);
    mImageSkyDay.onDraw(canvas, height, width, mOffsetVertical);

    mImageMoon.onDraw(canvas, height, mOffsetVertical + moonOffset);
    mImageSun.onDraw(canvas, height, mOffsetVertical + sunOffset);

    mImagePlane.onDraw(
        canvas,
        height,
        width,
        mImageVillage.geTotalWidthScaled(height),
        mOffsetVertical,
        offsetHorizontal);

    mImageClouds.onDraw(canvas, height, width, mOffsetVertical);

    mImageMountainsNight.onDraw(canvas, height, width, mOffsetVertical, offsetHorizontal);
    mPaintMountainsNight.onDraw(canvas, height, width, mOffsetVertical);
    mImageMountainsDay.onDraw(canvas, height, width, mOffsetVertical, offsetHorizontal);
    mPaintMountainsDay.onDraw(canvas, height, width, mOffsetVertical);

    mImageRail.onDraw(canvas, height, width, mOffsetVertical, offsetHorizontal);
    mImageMonoRail.onDraw(
        canvas,
        height,
        width,
        mImageVillage.geTotalWidthScaled(height),
        mOffsetVertical,
        offsetHorizontal);

    mImageVillage.onDraw(canvas, height, width, mOffsetVertical, offsetHorizontal);
    mImageSnow.onDraw(canvas, height, width, mOffsetVertical, offsetHorizontal);
    mPaintSnow.onDraw(canvas, height, width, mOffsetVertical);

    // UFO shouldn't fly across the full village width. Lets do 3 screen widths
    mImageUfo.onDraw(canvas, height, width, 3 * width, mOffsetVertical, 0);

    long currentTime = System.currentTimeMillis();
    float offsetIncrement;
    if (mLastFrameTime != 0) {
      offsetIncrement = (float) ((currentTime - mLastFrameTime)) / 1000f * mScrollPerSecond;
    } else {
      offsetIncrement = 0;
    }

    if (mAnimate) {
      if (mDirectionForward) {
        mTimedOffsetHorizontal += offsetIncrement; // Offset image
        // If the offset has hit the end, reverse direction
        if (mTimedOffsetHorizontal >= mMaxOffsetHorizontalVillage) {
          mDirectionForward = false;
          mTimedOffsetHorizontal = mMaxOffsetHorizontalVillage;
        }
      } else {
        mTimedOffsetHorizontal -= offsetIncrement;
        if (mTimedOffsetHorizontal <= -mMaxOffsetHorizontalVillage) {
          mDirectionForward = true;
          mTimedOffsetHorizontal = -mMaxOffsetHorizontalVillage;
        }
      }
    }
    mLastFrameTime = currentTime;
  }
  public void initialiseVillageViews(int viewHeight, int viewWidth) {
    mViewHeight = viewHeight;
    int maxDimension = viewHeight > viewWidth ? viewHeight : viewWidth;
    Resources resources = getResources();
    if (!mImagesInitialised) {
      UiModeManager mgr =
          (UiModeManager)
              getActivity().getApplicationContext().getSystemService(Context.UI_MODE_SERVICE);
      if (Configuration.UI_MODE_TYPE_WATCH == mgr.getCurrentModeType()) {
        int referenceHeight = resources.getInteger(R.integer.wear_referenceHeight);

        mImageSkyDay =
            new StretchedFullWidthImage(
                R.drawable.sky_day,
                resources.getInteger(R.integer.wear_skyReferenceHeight),
                resources.getInteger(R.integer.wear_skyStart));
        mImageSkyNight =
            new StretchedFullWidthImage(
                R.drawable.sky_night,
                resources.getInteger(R.integer.wear_skyReferenceHeight),
                resources.getInteger(R.integer.wear_skyStart));
        mImageUfo =
            new HorizontalScrollingImage(
                R.drawable.ufo,
                referenceHeight,
                resources.getInteger(R.integer.wear_ufoVerticalOffset),
                false,
                resources.getInteger(R.integer.wear_ufoPercentagePerSecond));
        mImageSun =
            new SimpleImage(
                R.drawable.sun,
                resources.getInteger(R.integer.wear_sunReferenceHeight),
                resources.getInteger(R.integer.wear_sunVerticalOffset),
                resources.getInteger(R.integer.wear_sunHorizontalOffset));
        mImageMoon =
            new SimpleImage(
                R.drawable.moon,
                resources.getInteger(R.integer.wear_sunReferenceHeight),
                resources.getInteger(R.integer.wear_moonVerticalOffset),
                resources.getInteger(R.integer.wear_moonHorizontalOffset));
        mImagePlane =
            new HorizontalScrollingImage(
                R.drawable.plane,
                referenceHeight,
                resources.getInteger(R.integer.wear_planeVerticalOffset),
                true,
                resources.getInteger(R.integer.wear_planePercentagePerSecond));

        mImageClouds =
            new HorizontalScrollingImageGroup(
                R.drawable.cloud,
                resources.getInteger(R.integer.wear_numClouds),
                resources.getInteger(R.integer.wear_sunVerticalOffset),
                resources.getInteger(R.integer.wear_cloudsEnd),
                getParallax(R.integer.wear_cloudsParallax),
                referenceHeight);
        mImageMountainsDay =
            loadImage(
                R.array.wear_mountainsDayIds,
                referenceHeight,
                R.integer.wear_mountainsStart,
                R.integer.wear_mountainsParallax,
                R.integer.wear_med_res);
        mImageMountainsNight =
            loadImage(
                R.array.wear_mountainsNightIds,
                referenceHeight,
                R.integer.wear_mountainsStart,
                R.integer.wear_mountainsParallax,
                R.integer.wear_med_res);
        mPaintMountainsDay =
            new SolidPaint(
                getString(R.color.colorMountainsDay),
                resources.getInteger(R.integer.wear_mountainsPaintStart),
                resources.getInteger(R.integer.wear_mountainsEnd),
                referenceHeight);
        mPaintMountainsNight =
            new SolidPaint(
                getString(R.color.colorMountainsNight),
                resources.getInteger(R.integer.wear_mountainsPaintStart),
                resources.getInteger(R.integer.wear_mountainsEnd),
                referenceHeight);

        mImageMonoRail =
            new HorizontalScrollingImage(
                R.drawable.monorail,
                referenceHeight,
                resources.getInteger(R.integer.wear_monorailStart),
                false,
                resources.getInteger(R.integer.wear_monorailPercentagePerSecond));
        mImageRail =
            new HorizontallyRepeatingImage(
                R.drawable.rail,
                referenceHeight,
                resources.getInteger(R.integer.wear_railStart),
                getParallax(R.integer.wear_railParallax));

        mImageVillage =
            loadImage(
                R.array.wear_villageIds,
                referenceHeight,
                R.integer.wear_villageStart,
                R.integer.wear_villageParallax,
                R.integer.wear_high_res);
        mImageSnow =
            loadImage(
                R.array.wear_snowIds,
                referenceHeight,
                R.integer.wear_snowStart,
                R.integer.wear_snowParallax,
                R.integer.wear_low_res);
        mPaintSnow =
            new SolidPaint(
                getString(R.color.colorSnow),
                resources.getInteger(R.integer.wear_snowPaintStart),
                resources.getInteger(R.integer.wear_snowEnd),
                referenceHeight);

        mOffsetVertical = -1 * resources.getInteger(R.integer.wear_verticalOffset);
      } else {
        int referenceHeight = resources.getInteger(R.integer.referenceHeight);

        mImageSkyDay =
            new StretchedFullWidthImage(
                R.drawable.sky_day,
                resources.getInteger(R.integer.skyReferenceHeight),
                resources.getInteger(R.integer.skyStart));
        mImageSkyNight =
            new StretchedFullWidthImage(
                R.drawable.sky_night,
                resources.getInteger(R.integer.skyReferenceHeight),
                resources.getInteger(R.integer.skyStart));
        mImageUfo =
            new HorizontalScrollingImage(
                R.drawable.ufo,
                referenceHeight,
                resources.getInteger(R.integer.ufoVerticalOffset),
                false,
                resources.getInteger(R.integer.ufoPercentagePerSecond));
        mImageSun =
            new SimpleImage(
                R.drawable.sun,
                resources.getInteger(R.integer.sunReferenceHeight),
                resources.getInteger(R.integer.sunVerticalOffset),
                resources.getInteger(R.integer.sunHorizontalOffset));
        mImageMoon =
            new SimpleImage(
                R.drawable.moon,
                resources.getInteger(R.integer.sunReferenceHeight),
                resources.getInteger(R.integer.moonVerticalOffset),
                resources.getInteger(R.integer.moonHorizontalOffset));
        mImagePlane =
            new HorizontalScrollingImage(
                R.drawable.plane,
                referenceHeight,
                resources.getInteger(R.integer.planeVerticalOffset),
                true,
                resources.getInteger(R.integer.wear_planePercentagePerSecond));

        mImageClouds =
            new HorizontalScrollingImageGroup(
                R.drawable.cloud,
                resources.getInteger(R.integer.numClouds),
                resources.getInteger(R.integer.sunVerticalOffset),
                resources.getInteger(R.integer.cloudsEnd),
                getParallax(R.integer.cloudsParallax),
                referenceHeight);
        mImageMountainsDay =
            loadImage(
                R.array.mountainsDayIds,
                referenceHeight,
                R.integer.mountainsStart,
                R.integer.mountainsParallax,
                R.integer.med_res);
        mImageMountainsNight =
            loadImage(
                R.array.mountainsNightIds,
                referenceHeight,
                R.integer.mountainsStart,
                R.integer.mountainsParallax,
                R.integer.med_res);
        mPaintMountainsDay =
            new SolidPaint(
                getString(R.color.colorMountainsDay),
                resources.getInteger(R.integer.mountainsPaintStart),
                resources.getInteger(R.integer.mountainsEnd),
                referenceHeight);
        mPaintMountainsNight =
            new SolidPaint(
                getString(R.color.colorMountainsNight),
                resources.getInteger(R.integer.mountainsPaintStart),
                resources.getInteger(R.integer.mountainsEnd),
                referenceHeight);

        mImageMonoRail =
            new HorizontalScrollingImage(
                R.drawable.monorail,
                referenceHeight,
                resources.getInteger(R.integer.monorailStart),
                false,
                resources.getInteger(R.integer.wear_monorailPercentagePerSecond));
        mImageRail =
            new HorizontallyRepeatingImage(
                R.drawable.rail,
                referenceHeight,
                resources.getInteger(R.integer.railStart),
                getParallax(R.integer.railParallax));

        mImageVillage =
            loadImage(
                R.array.villageIds,
                referenceHeight,
                R.integer.villageStart,
                R.integer.villageParallax,
                R.integer.high_res);
        mImageSnow =
            loadImage(
                R.array.snowIds,
                referenceHeight,
                R.integer.snowStart,
                R.integer.snowParallax,
                R.integer.low_res);
        mPaintSnow =
            new SolidPaint(
                getString(R.color.colorSnow),
                resources.getInteger(R.integer.snowPaintStart),
                resources.getInteger(R.integer.snowEnd),
                referenceHeight);
      }

      mImageSkyDay.loadImages(resources);
      mImageSkyNight.loadImages(resources);
      mImageUfo.loadImages(resources);
      mImageSun.loadImages(resources);
      mImageMoon.loadImages(resources);
      mImagePlane.loadImages(resources);

      mImageClouds.loadImages(resources);
      mImageMountainsDay.loadImages(resources);
      mImageMountainsNight.loadImages(resources);

      mImageMonoRail.loadImages(resources);
      mImageRail.loadImages(resources);

      mImageVillage.loadImages(resources);
      mImageSnow.loadImages(getResources());

      mImagesInitialised = true;

      setIsDay(initialiseSunMoon(), false);
    }

    // Set easter egg state to empty
    for (int i = 0; i < EGG_COUNT; i++) {
      mEasterEggTracker[i] = false;
    }
    mImageUfo.setAlpha(ImageWithAlphaAndSize.INVISIBLE);

    mMaxOffsetHorizontalVillage = mImageVillage.geTotalWidthScaled(viewHeight) / 2;
    int percentPerSecond = getResources().getInteger(R.integer.scrollPercentagePerSecond);
    mScrollPerSecond = (float) (percentPerSecond) / 100f * maxDimension;
  }