content: /*
   * Copyright (C) 2011 The Android Open Source Project
   *
   * 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 com.lb.launcher;
  
  import android.animation.LayoutTransition;
  import android.content.Context;
  import android.content.res.TypedArray;
  import android.util.AttributeSet;
  import android.view.LayoutInflater;
  import android.widget.LinearLayout;
  import java.util.ArrayList;
  import com.lb.launcher.R;
  
  public class PageIndicator extends LinearLayout {
      @SuppressWarnings("unused")
      private static final String TAG = "PageIndicator";
      // Want this to look good? Keep it odd
      private static final boolean MODULATE_ALPHA_ENABLED = false;
  
      private LayoutInflater mLayoutInflater;
      private int[] mWindowRange = new int[2];
      private int mMaxWindowSize;
  
      private ArrayList<PageIndicatorMarker> mMarkers =
              new ArrayList<PageIndicatorMarker>();
      private int mActiveMarkerIndex;
  
      public static class PageMarkerResources {
          int activeId;
          int inactiveId;
  
          public PageMarkerResources() {
              activeId = R.drawable.ic_pageindicator_current;
              inactiveId = R.drawable.ic_pageindicator_default;
          }
          public PageMarkerResources(int aId, int iaId) {
              activeId = aId;
              inactiveId = iaId;
          }
      }
  
      public PageIndicator(Context context) {
          this(context, null);
      }
  
      public PageIndicator(Context context, AttributeSet attrs) {
          this(context, attrs, 0);
      }
  
      public PageIndicator(Context context, AttributeSet attrs, int defStyle) {
          super(context, attrs, defStyle);
          TypedArray a = context.obtainStyledAttributes(attrs,
                  R.styleable.PageIndicator, defStyle, 0);
          mMaxWindowSize = a.getInteger(R.styleable.PageIndicator_windowSize, 15);
          mWindowRange[0] = 0;
          mWindowRange[1] = 0;
          mLayoutInflater = LayoutInflater.from(context);
          a.recycle();
  
          // Set the layout transition properties
          LayoutTransition transition = getLayoutTransition();
          transition.setDuration(175);
      }
  
      private void enableLayoutTransitions() {
          LayoutTransition transition = getLayoutTransition();
          transition.enableTransitionType(LayoutTransition.APPEARING);
          transition.enableTransitionType(LayoutTransition.DISAPPEARING);
          transition.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
          transition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
      }
  
      private void disableLayoutTransitions() {
          LayoutTransition transition = getLayoutTransition();
          transition.disableTransitionType(LayoutTransition.APPEARING);
          transition.disableTransitionType(LayoutTransition.DISAPPEARING);
          transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
          transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
      }
  
      void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
          if (activeIndex < 0) {
              new Throwable().printStackTrace();
          }
          int windowSize = Math.min(mMarkers.size(), mMaxWindowSize);
          int hWindowSize = (int) windowSize / 2;
          float hfWindowSize = windowSize / 2f;
          int windowStart = Math.max(0, activeIndex - hWindowSize);
          int windowEnd = Math.min(mMarkers.size(), windowStart + mMaxWindowSize);
          windowStart = windowEnd - Math.min(mMarkers.size(), windowSize);
          int windowMid = windowStart + (windowEnd - windowStart) / 2;
          boolean windowAtStart = (windowStart == 0);
          boolean windowAtEnd = (windowEnd == mMarkers.size());
          boolean windowMoved = (mWindowRange[0] != windowStart) ||
                  (mWindowRange[1] != windowEnd);
  
          if (!allowAnimations) {
              disableLayoutTransitions();
          }
  
          // Remove all the previous children that are no longer in the window
          for (int i = getChildCount() - 1; i >= 0; --i) {
              PageIndicatorMarker marker = (PageIndicatorMarker) getChildAt(i);
              int markerIndex = mMarkers.indexOf(marker);
              if (markerIndex < windowStart || markerIndex >= windowEnd) {
                  removeView(marker);
              }
          }
  
          // Add all the new children that belong in the window
          for (int i = 0; i < mMarkers.size(); ++i) {
              PageIndicatorMarker marker = (PageIndicatorMarker) mMarkers.get(i);
              if (windowStart <= i && i < windowEnd) {
                  if (indexOfChild(marker) < 0) {
                      addView(marker, i - windowStart);
                  }
                  if (i == activeIndex) {
                      marker.activate(windowMoved);
                  } else {
                      marker.inactivate(windowMoved);
                  }
              } else {
                  marker.inactivate(true);
              }
  
              if (MODULATE_ALPHA_ENABLED) {
                  // Update the marker's alpha
                  float alpha = 1f;
                  if (mMarkers.size() > windowSize) {
                      if ((windowAtStart && i > hWindowSize) ||
                          (windowAtEnd && i < (mMarkers.size() - hWindowSize)) ||
                          (!windowAtStart && !windowAtEnd)) {
                          alpha = 1f - Math.abs((i - windowMid) / hfWindowSize);
                      }
                  }
                  marker.animate().alpha(alpha).setDuration(500).start();
              }
          }
  
          if (!allowAnimations) {
              enableLayoutTransitions();
          }
  
          mWindowRange[0] = windowStart;
          mWindowRange[1] = windowEnd;
      }
  
      void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
          index = Math.max(0, Math.min(index, mMarkers.size()));
  
          PageIndicatorMarker m =
              (PageIndicatorMarker) mLayoutInflater.inflate(R.layout.page_indicator_marker,
                      this, false);
          m.setMarkerDrawables(marker.activeId, marker.inactiveId);
  
          mMarkers.add(index, m);
          offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
      }
      void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
          for (int i = 0; i < markers.size(); ++i) {
              addMarker(Integer.MAX_VALUE, markers.get(i), allowAnimations);
          }
      }
  
      void updateMarker(int index, PageMarkerResources marker) {
          PageIndicatorMarker m = mMarkers.get(index);
          m.setMarkerDrawables(marker.activeId, marker.inactiveId);
      }
  
      void removeMarker(int index, boolean allowAnimations) {
          if (mMarkers.size() > 0) {
              index = Math.max(0, Math.min(mMarkers.size() - 1, index));
              mMarkers.remove(index);
              offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
          }
      }
      void removeAllMarkers(boolean allowAnimations) {
          while (mMarkers.size() > 0) {
              removeMarker(Integer.MAX_VALUE, allowAnimations);
          }
      }
  
      void setActiveMarker(int index) {
          // Center the active marker
          mActiveMarkerIndex = index;
          offsetWindowCenterTo(index, false);
      }
  
      void dumpState(String txt) {
          System.out.println(txt);
          System.out.println("\tmMarkers: " + mMarkers.size());
          for (int i = 0; i < mMarkers.size(); ++i) {
              PageIndicatorMarker m = mMarkers.get(i);
              System.out.println("\t\t(" + i + ") " + m);
          }
          System.out.println("\twindow: [" + mWindowRange[0] + ", " + mWindowRange[1] + "]");
          System.out.println("\tchildren: " + getChildCount());
          for (int i = 0; i < getChildCount(); ++i) {
              PageIndicatorMarker m = (PageIndicatorMarker) getChildAt(i);
              System.out.println("\t\t(" + i + ") " + m);
          }
          System.out.println("\tactive: " + mActiveMarkerIndex);
      }
  }
  