content: package com.alimuzaffar.ramadanalarm.fragments;
  
  
  import android.Manifest;
  import android.app.Activity;
  import android.app.Fragment;
  import android.content.DialogInterface;
  import android.content.pm.PackageManager;
  import android.graphics.Color;
  import android.hardware.Sensor;
  import android.hardware.SensorEvent;
  import android.hardware.SensorEventListener;
  import android.hardware.SensorManager;
  import android.location.Location;
  import android.os.Bundle;
  import android.support.v7.app.AlertDialog;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.CheckBox;
  import android.widget.CompoundButton;
  
  import com.alimuzaffar.ramadanalarm.BuildConfig;
  import com.alimuzaffar.ramadanalarm.Constants;
  import com.alimuzaffar.ramadanalarm.R;
  import com.alimuzaffar.ramadanalarm.util.AppSettings;
  import com.alimuzaffar.ramadanalarm.util.PermissionUtil;
  import com.google.android.gms.maps.CameraUpdateFactory;
  import com.google.android.gms.maps.GoogleMap;
  import com.google.android.gms.maps.GoogleMapOptions;
  import com.google.android.gms.maps.MapFragment;
  import com.google.android.gms.maps.OnMapReadyCallback;
  import com.google.android.gms.maps.model.BitmapDescriptorFactory;
  import com.google.android.gms.maps.model.CameraPosition;
  import com.google.android.gms.maps.model.LatLng;
  import com.google.android.gms.maps.model.MarkerOptions;
  import com.google.android.gms.maps.model.PolylineOptions;
  
  /**
   * A simple {@link Fragment} subclass.
   */
  public class KaabaLocatorFragment extends Fragment implements Constants, OnMapReadyCallback, SensorEventListener {
  
    Location mLastLocation;
    MapFragment mMapFragment;
    GoogleMap mMap;
  
  //  private float currentDegree = 0f;
    private SensorManager mSensorManager;
  
    private float[] mRotationMatrix = new float[16];
    private float[] mValues = new float[3];
  
    private boolean mRegistered = false;
    private static boolean sWriterExternalPermissionDenied;
  
    public KaabaLocatorFragment() {
      // Required empty public constructor
    }
  
    public static KaabaLocatorFragment newInstance(Location location) {
      KaabaLocatorFragment fragment = new KaabaLocatorFragment();
      Bundle args = new Bundle();
      args.putParcelable(EXTRA_LAST_LOCATION, location);
      fragment.setArguments(args);
      return fragment;
    }
  
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      if (getArguments() != null) {
        mLastLocation = (Location) getArguments().getParcelable(EXTRA_LAST_LOCATION);
      }
    }
  
    @Override
    public void onAttach(Activity activity) {
      super.onAttach(activity);
      mSensorManager = (SensorManager) activity.getSystemService(Activity.SENSOR_SERVICE);
    }
  
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
      // Inflate the layout for this fragment
      View view = inflater.inflate(R.layout.fragment_kaaba_locator, container, false);
      view.findViewById(R.id.grant).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          checkPermissions();
        }
      });
      return view;
    }
  
    private boolean checkPermissions() {
      if (!PermissionUtil.hasSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        if (!sWriterExternalPermissionDenied) {
          requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL);
        } else {
          // Perhaps inform the user why they aren't seeing anything.
        }
        return false;
      }
      return true;
    }
  
    public void showMap() {
      if (!PermissionUtil.hasSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        throw new IllegalStateException("WRITE_EXTERNAL_STORAGE permission should be granted before this method is called.");
      }
  
      if (mMapFragment == null) {
        mMapFragment = (MapFragment) getFragmentManager().findFragmentByTag("map_fragment");
      }
  
      if (mMapFragment == null) {
        GoogleMapOptions options = new GoogleMapOptions()
                .rotateGesturesEnabled(false)
                .tiltGesturesEnabled(false)
                .compassEnabled(true)
                .zoomControlsEnabled(false)
                .zoomGesturesEnabled(true)
                .scrollGesturesEnabled(true);
        mMapFragment = MapFragment.newInstance(options);
      }
  
      if (mMap == null && !mMapFragment.isAdded()) {
        ((ViewGroup) getView().findViewById(R.id.map_container)).removeAllViews();
        getFragmentManager().beginTransaction().add(R.id.map_container, mMapFragment, "map_fragment").commit();
        mMapFragment.getMapAsync(this);
        showOrientationDialog();
      } else {
        registerRotationListener();
      }
    }
  
    public void hideMap() {
      unregisterRotationListener();
    }
  
    @Override
    public void onMapReady(GoogleMap map) {
      mMap = map;
      if (mLastLocation != null) {
        initMap();
      }
    }
  
    private void initMap() {
      if (mMap == null && mLastLocation == null) {
        Log.w("KabaaLocatorFragment", "Ignoring since mMap or mLastLocation is null");
        return;
      }
  
      registerRotationListener();
  
      LatLng startPosition = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
      //21.4224698,39.8262066
      LatLng kaaba = new LatLng(21.4224698, 39.8262066);
  
      mMap.setMyLocationEnabled(true);
      mMap.getUiSettings().setMyLocationButtonEnabled(true);
      mMap.getUiSettings().setCompassEnabled(false);
      mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(startPosition, 13));
      //mMap.getUiSettings().setRotateGesturesEnabled(false);
  
      mMap.clear();
  
      mMap.addMarker(new MarkerOptions()
          .title(getString(R.string.kaaba))
          .position(kaaba));
  
      mMap.addMarker(new MarkerOptions()
          .icon(BitmapDescriptorFactory.fromResource(R.drawable.compass))
          .title(getString(R.string.current_location))
          .position(startPosition));
  
      // Polylines are useful for marking paths and routes on the map.
      mMap.addPolyline(new PolylineOptions().geodesic(true)
          .add(startPosition)  // user position
          .add(kaaba)
          .color(Color.RED));  // Kaabah
  
    }
  
    public void setLocation(Location location) {
      mLastLocation = location;
      initMap();
    }
  
    @Override
    public void onResume() {
      super.onResume();
      registerRotationListener();
    }
  
    @Override
    public void onPause() {
      super.onPause();
      unregisterRotationListener();
    }
  
    private void registerRotationListener() {
      if (mMap != null && mLastLocation != null && !mRegistered) {
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_UI);
        mRegistered = true;
      }
    }
  
    private void unregisterRotationListener() {
      if (mRegistered) {
        mSensorManager.unregisterListener(this);
        mRegistered = false;
      }
    }
  
    @Override
    public void onSensorChanged(SensorEvent event) {
      if (mLastLocation == null) {
        return;
      }
      SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
      SensorManager.getOrientation(mRotationMatrix, mValues);
  
      /*
      if (BuildConfig.DEBUG) {
        System.out.println("sensorChanged (" + Math.toDegrees(mValues[0]) + ", " + Math.toDegrees(mValues[1]) + ", " + Math.toDegrees(mValues[2]) + ")");
      }
      */
  
      float bearing = 0f;
  
      if (mMap != null) {
        bearing = Double.valueOf(mMap.getCameraPosition().bearing).floatValue();
      }
  
      // get the angle around the z-axis rotated
      float degree = Double.valueOf(Math.toDegrees(mValues[0])).floatValue();
  
      if (Math.round(bearing) == Math.round(degree)) {
        System.out.println("bearing and degrees are the same.");
        return;
      }
  
      if (BuildConfig.DEBUG) {
        System.out.println("degrees " + degree + ", bearing " + bearing);
      }
  
      //tvHeading.setText("Heading: " + Float.toString(degree) + " degrees");
  
      CameraPosition cameraPosition = mMap.getCameraPosition();
      CameraPosition newPosition = new CameraPosition(cameraPosition.target, cameraPosition.zoom, cameraPosition.tilt, degree);
      mMap.moveCamera(CameraUpdateFactory.newCameraPosition(newPosition));
      // create a rotation animation (reverse turn degree degrees)
      /*
      RotateAnimation ra = new RotateAnimation(
              currentDegree,
              -degree-180,
              Animation.RELATIVE_TO_SELF, 0.5f,
              Animation.RELATIVE_TO_SELF,
              0.5f);
  
      // how long the animation will take place
      ra.setDuration(210);
  
      // set the animation after the end of the reservation status
      ra.setFillAfter(true);
  
      // Start the animation
      mCompass.startAnimation(ra);
      currentDegree = -degree-180;
      */
    }
  
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
  
    }
  
    /**
     * Callback received when a permissions request has been completed.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
  
      if (requestCode == REQUEST_WRITE_EXTERNAL) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
         showMap();
        } else {
          Log.i("BaseActivity", "LOCATION permission was NOT granted.");
          sWriterExternalPermissionDenied = true;
        }
  
      } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      }
    }
  
    private void showOrientationDialog() {
      if (!AppSettings.getInstance().getBoolean(AppSettings.Key.SHOW_ORIENATATION_INSTRACTIONS, true)) {
        return;
      }
      View v = getActivity().getLayoutInflater().inflate(R.layout.view_orientation_instructions, null);
      AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
      alertBuilder.setView(v)
          .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
              dialog.dismiss();
            }
          });
  
      CheckBox doNotShow = (CheckBox) v.findViewById(R.id.checkbox_no_show);
      doNotShow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
          AppSettings.getInstance().set(AppSettings.Key.SHOW_ORIENATATION_INSTRACTIONS, !isChecked);
        }
      });
  
      alertBuilder.create().show();
    }
  
  }
  