/** Returns the 3D renderer context for PicSphere capture mode */
  public Capture3DRenderer getRenderer() {
    if (mCapture3DRenderer == null) {
      // Initialize the 3D renderer
      mCapture3DRenderer = new Capture3DRenderer(mContext, mContext.getCamManager());

      // We route the camera preview to our texture
      mGLRootView = (FrameLayout) mContext.findViewById(R.id.gl_renderer_container);
    }

    return mCapture3DRenderer;
  }
  /** Check the capabilities of the device, and populate the sidebar with the toggle buttons. */
  public void checkCapabilities(CameraActivity activity, ViewGroup widgetsContainer) {
    mToggleContainer = (ViewGroup) this.getChildAt(0);

    if (mCapabilities != null) {
      mToggleContainer.removeAllViews();
      mCapabilities = null;
    }

    mCapabilities = new CameraCapabilities(activity);
    Camera.Parameters params = activity.getCamManager().getParameters();

    if (params != null) {
      mCapabilities.populateSidebar(params, mToggleContainer, widgetsContainer);
    } else {
      Log.e(TAG, "Parameters were null when capabilities were checked");
    }
  }
  public SettingsWidget(CameraActivity context, CameraCapabilities capabilities) {
    super(context.getCamManager(), context, R.drawable.ic_widget_settings);
    mContext = context;
    mCapabilities = capabilities;

    CameraManager cam = context.getCamManager();

    getToggleButton().setHintText(R.string.widget_settings);

    if (CameraActivity.getCameraMode() == CameraActivity.CAMERA_MODE_PHOTO
        || CameraActivity.getCameraMode() == CameraActivity.CAMERA_MODE_PICSPHERE) {
      // Get the available photo size. Unlike AOSP app, we don't
      // store manually each resolution in an XML, but we calculate it directly
      // from the width and height of the picture size.
      mResolutions = cam.getParameters().getSupportedPictureSizes();
      mResolutionsName = new ArrayList<String>();

      DecimalFormat df = new DecimalFormat();
      df.setMaximumFractionDigits(1);
      df.setMinimumFractionDigits(0);
      df.setDecimalSeparatorAlwaysShown(false);

      Collections.sort(mResolutions, mResolutionsSorter);

      for (Camera.Size size : mResolutions) {
        float megapixels = size.width * size.height / 1000000.0f;
        mResolutionsName.add(df.format(megapixels) + "MP (" + size.width + "x" + size.height + ")");
      }

      // Restore picture size if we have any
      String resolution = "";
      if (CameraActivity.getCameraMode() == CameraActivity.CAMERA_MODE_PHOTO) {
        resolution =
            SettingsStorage.getCameraSetting(
                context,
                mCamManager.getCurrentFacing(),
                "picture-size",
                "" + mResolutions.get(0).width + "x" + mResolutions.get(0).height);
      } else {
        resolution =
            SettingsStorage.getCameraSetting(
                context, mCamManager.getCurrentFacing(), "picsphere-picture-size", "640x480");
      }
      mCamManager.setPictureSize(resolution);
    } else if (CameraActivity.getCameraMode() == CameraActivity.CAMERA_MODE_VIDEO) {
      mResolutions = cam.getParameters().getSupportedVideoSizes();
      mResolutionsName = new ArrayList<String>();
      mVideoResolutions = new ArrayList<String>();

      if (mResolutions != null) {
        // We support a fixed set of video resolutions (pretty much like AOSP)
        // because we need to take the CamcorderProfile (media_profiles.xml), which
        // has a fixed set of values...
        for (Camera.Size size : mResolutions) {
          if (size.width == 1920 && size.height == 1080
              || size.width == 1920 && size.height == 1088) {
            mResolutionsName.add(mContext.getString(R.string.video_res_1080p));
            mVideoResolutions.add("1920x1080");
          } else if (size.width == 1280 && size.height == 720) {
            mResolutionsName.add(mContext.getString(R.string.video_res_720p));
            mVideoResolutions.add("1280x720");
          } else if (size.width == 720 && size.height == 480) {
            mResolutionsName.add(mContext.getString(R.string.video_res_480p));
            mVideoResolutions.add("720x480");
          } else if (size.width == 352 && size.height == 288) {
            mResolutionsName.add(mContext.getString(R.string.video_res_mms));
            mVideoResolutions.add("352x288");
          }
        }
      } else if (mResolutions == null || mResolutions.size() == 0) {
        // We detected no compatible video resolution! We add default ones.
        mResolutionsName.add(mContext.getString(R.string.video_res_1080p));
        mVideoResolutions.add("1920x1080");
        mResolutionsName.add(mContext.getString(R.string.video_res_720p));
        mVideoResolutions.add("1280x720");
        mResolutionsName.add(mContext.getString(R.string.video_res_480p));
        mVideoResolutions.add("720x480");
      }

      // TODO: Restore video size if we have any
      String resolution =
          SettingsStorage.getCameraSetting(
              context, mCamManager.getCurrentFacing(), "video-size", mVideoResolutions.get(0));
      applyVideoResolution(resolution);
    }

    mResolutionButton = new WidgetOptionButton(R.drawable.ic_widget_settings_resolution, context);
    mResolutionButton.setOnClickListener(mResolutionClickListener);
    mResolutionButton.setHintText(mContext.getString(R.string.widget_settings_picture_size));
    addViewToContainer(mResolutionButton);

    if (mCamManager.isExposureAreaSupported()
        && CameraActivity.getCameraMode() != CameraActivity.CAMERA_MODE_PICSPHERE) {
      mToggleExposureRing =
          new WidgetOptionButton(R.drawable.ic_widget_settings_exposurering, context);
      mToggleExposureRing.setHintText(mContext.getString(R.string.widget_settings_exposure_ring));
      mToggleExposureRing.setOnClickListener(mExpoRingClickListener);

      // Restore exposure ring state
      if (SettingsStorage.getAppSetting(mContext, KEY_SHOW_EXPOSURE_RING, "0").equals("1")) {
        mContext.setExposureRingVisible(true);
        mToggleExposureRing.activeImage(DRAWABLE_KEY_EXPO_RING);
      } else {
        mContext.setExposureRingVisible(false);
      }
      addViewToContainer(mToggleExposureRing);
    }

    // Toggle auto enhancer
    if (CameraActivity.getCameraMode() != CameraActivity.CAMERA_MODE_PICSPHERE) {
      mToggleAutoEnhancer = new WidgetOptionButton(R.drawable.ic_enhancing, context);
      mToggleAutoEnhancer.setOnClickListener(mAutoEnhanceClickListener);
      mToggleAutoEnhancer.setHintText(mContext.getString(R.string.widget_settings_autoenhance));

      // Restore auto enhancer state
      if (SettingsStorage.getAppSetting(mContext, KEY_ENABLE_AUTO_ENHANCE, "0").equals("1")) {
        mContext.getSnapManager().setAutoEnhance(true);
        mToggleAutoEnhancer.activeImage(DRAWABLE_KEY_AUTO_ENHANCE);
      } else {
        if (mContext.getSnapManager() != null) {
          mContext.getSnapManager().setAutoEnhance(false);
        }
      }

      addViewToContainer(mToggleAutoEnhancer);

      // Toggle rule of thirds
      mToggleRuleOfThirds =
          new WidgetOptionButton(R.drawable.ic_widget_settings_rulethirds, context);
      mToggleRuleOfThirds.setOnClickListener(mRuleOfThirdsClickListener);
      mToggleRuleOfThirds.setHintText(mContext.getString(R.string.widget_settings_ruleofthirds));

      // Restore rule of thirds visibility state
      if (SettingsStorage.getAppSetting(mContext, KEY_ENABLE_RULE_OF_THIRDS, "0").equals("1")) {
        mContext.findViewById(R.id.rule_of_thirds).setVisibility(View.VISIBLE);
        mToggleRuleOfThirds.activeImage(KEY_ENABLE_RULE_OF_THIRDS);
      } else {
        mContext.findViewById(R.id.rule_of_thirds).setVisibility(View.GONE);
        mToggleRuleOfThirds.resetImage();
      }

      addViewToContainer(mToggleRuleOfThirds);
    }

    // Choose widgets to appear
    mToggleWidgetsButton = new WidgetOptionButton(R.drawable.ic_widget_settings_widgets, context);
    mToggleWidgetsButton.setHintText(
        mContext.getString(R.string.widget_settings_choose_widgets_button));
    mToggleWidgetsButton.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            openWidgetsToggleDialog();
          }
        });
    addViewToContainer(mToggleWidgetsButton);
  }