package site.duqian.wchook.android;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.CameraPosition;

import site.duqian.wchook.MainActivity;
import site.duqian.wchook.R;
import site.duqian.wchook.common.ApiUtil;
import site.duqian.wchook.model.MyCallBack;
import site.duqian.wchook.utils.LogUtils;
import site.duqian.wchook.utils.ToastUtil;
import site.duqian.wchook.xposed.SettingsHelper;

import static site.duqian.wchook.model.Constant.MAP_DEFAULT_LATITUDE;
import static site.duqian.wchook.model.Constant.MAP_DEFAULT_LONGITUDE;
import static site.duqian.wchook.model.Constant.SP_ADDRESS;
import static site.duqian.wchook.model.Constant.SP_LATITUDE;
import static site.duqian.wchook.model.Constant.SP_LONGITUDE;

/**
 * Created by Dusan (duqian) on 2017/5/6 - 20:56.
 * E-mail: [email protected]
 * Description:MapActivity 高德地图 google map
 * remarks:
 */
public class MapActivity extends FragmentActivity implements View.OnClickListener,
        AMap.OnCameraChangeListener, OnMapReadyCallback,
        GoogleMap.OnCameraMoveListener, AMapLocationListener,
        CompoundButton.OnCheckedChangeListener, AMap.OnMapClickListener{
    private static final String TAG = MapActivity.class.getSimpleName();
    private ToggleButton mcheckbtn;
    private Button mapbtn;
    private Button btn_confirm;
    private TextView tv_position;
    private LinearLayout mContainerLayout;
    private LinearLayout.LayoutParams mParams;
    private TextureMapView mAmapView;
    private MapView mGoogleMapView;
    private float zoom = 10;
    private double latitude = 23.10485;
    private double longitude = 113.388975;
    private boolean mIsAmapDisplay = true;
    private boolean mIsAuto = true;
    private AMap amap;
    private GoogleMap googlemap;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private AlphaAnimation anappear;
    private AlphaAnimation andisappear;
    private Context context;
    private MapActivity activity;
    private GeocodeSearch geocoderSearch;
    private String formatAddress="";
    private SettingsHelper mSettings;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        context = this;
        activity = this;
        mSettings = new SettingsHelper(context);
        initView();
        initGDMap(savedInstanceState);
        configGDLocation();
        //changeToGoogleMapView();
        getLastPostion();
    }

    //标注上次保存的位置
    private void getLastPostion() {
        double latitude = Double.parseDouble(mSettings.getString(SP_LATITUDE, MAP_DEFAULT_LATITUDE));
        double longitude = Double.parseDouble(mSettings.getString(SP_LONGITUDE, MAP_DEFAULT_LONGITUDE));
        LatLng latLng = new LatLng(latitude,longitude);
        initGeocodeSearch(latLng);
    }

    // 中心点marker
    private Marker centerMarker;
    private BitmapDescriptor ICON_YELLOW = BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW);
    private BitmapDescriptor ICON_RED = BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_RED);
    private MarkerOptions markerOption = null;

    //高德地图
    @Override
    public void onMapClick(LatLng latLng) {
        longitude = latLng.longitude;
        latitude = latLng.latitude;
        initGeocodeSearch(latLng);
    }

    //高德地图,纬度/经度的反向地理编码
    private void initGeocodeSearch(LatLng latLng) {
        if (geocoderSearch==null) {
            geocoderSearch = new GeocodeSearch(this);
            geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
                @Override
                public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                    RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
                    formatAddress = regeocodeAddress.getFormatAddress();
                    LogUtils.debug(TAG,"regeocodeResult:"+ formatAddress);
                    setCurrentPositionInfo();
                    addCenterMarker(latLng);
                }

                @Override
                public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {}
            });
        }
        // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
        LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude,latLng.longitude);
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,GeocodeSearch.AMAP);
        geocoderSearch.getFromLocationAsyn(query);
    }

    private void setCurrentPositionInfo() {
        String position = "当前所选位置:经度:" + longitude + " 纬度:" + latitude+"\n"+formatAddress;
        LogUtils.debug(TAG, position);
        ToastUtil.toast(context, position);
        tv_position.setText(position);
        tv_position.setBackgroundColor(getResources().getColor(R.color.colorWhite));
    }

    private void addCenterMarker(LatLng latlng) {
        if (null == centerMarker) {
            markerOption = new MarkerOptions();
            markerOption.icon(ICON_RED);//ICON_RED  ICON_YELLOW
            centerMarker = amap.addMarker(markerOption);
            centerMarker.setPosition(latlng);
            centerMarker.setTitle("当前坐标:"+longitude+","+latitude+"\n"+formatAddress);
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        //setMapResult();
    }

    private void setMapResult() {
        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra(SP_LATITUDE, "" + latitude);
        intent.putExtra(SP_LONGITUDE, "" + longitude);
        intent.putExtra(SP_ADDRESS, "" + formatAddress);
        activity.setResult(100, intent);
        activity.finish();
    }

    private void configGDLocation() {
        //初始化client
        mlocationClient = new AMapLocationClient(this.getApplicationContext());
        // 设置定位监听
        mlocationClient.setLocationListener(this);
        //定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置为高精度定位模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        mLocationOption.setOnceLocation(true);
        //设置定位参数
        mlocationClient.setLocationOption(mLocationOption);
        mlocationClient.startLocation();

        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);//定位一次,且将视角移动到地图中心点。
        //myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
        //myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        amap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        amap.getUiSettings().setMyLocationButtonEnabled(true);//设置默认定位按钮是否显示,非必需设置。
        amap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
    }

    private void initView() {
        mContainerLayout = (LinearLayout) findViewById(R.id.map_container);
        tv_position = (TextView) findViewById(R.id.tv_position);
        btn_confirm = (Button) findViewById(R.id.btn_confirm);
        mapbtn = (Button) findViewById(R.id.btn_change_map);
        mcheckbtn = (ToggleButton) findViewById(R.id.btn_auto_change);
        mapbtn.setOnClickListener(this);
        mcheckbtn.setOnClickListener(this);
        mcheckbtn.setOnCheckedChangeListener(this);
        btn_confirm.setOnClickListener(this);
        mContainerLayout = (LinearLayout) findViewById(R.id.map_container);
    }

    private void initGDMap(Bundle savedInstanceState) {
        mAmapView = new TextureMapView(this);
        mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        mContainerLayout.addView(mAmapView, mParams);
        mAmapView.onCreate(savedInstanceState);
        if (amap == null) {
            amap = mAmapView.getMap();
            amap.setOnCameraChangeListener(this);
            amap.setOnMapClickListener(this);//new
        }
        anappear = new AlphaAnimation(0, 1);
        andisappear = new AlphaAnimation(1, 0);
        anappear.setDuration(5000);
        andisappear.setDuration(5000);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_auto_change:
                mIsAuto = mcheckbtn.isChecked();
                break;
            case R.id.btn_confirm:
                setMapResult();
                break;
            case R.id.btn_change_map:
                mcheckbtn.setChecked(false);
                mIsAuto = false;
                if (mIsAmapDisplay) {
                    changeToGoogleMapView();
                } else {
                    changeToAmapView();
                }
                break;
        }
    }

    private void changeToAmapView() {
        if (googlemap != null) {
            zoom = googlemap.getCameraPosition().zoom;
            latitude = googlemap.getCameraPosition().target.latitude;
            longitude = googlemap.getCameraPosition().target.longitude;
        }
        mapbtn.setText("To 谷歌地图");
        mAmapView = new TextureMapView(this, new AMapOptions()
                .camera(new com.amap.api.maps.model.CameraPosition(new LatLng(latitude, longitude), zoom, 0, 0)));
        mAmapView.onCreate(null);
        mAmapView.onResume();
        mContainerLayout.addView(mAmapView, mParams);

        mGoogleMapView.animate().alpha(0f).setDuration(500).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mGoogleMapView.setVisibility(View.GONE);
                mContainerLayout.removeView(mGoogleMapView);
                if (mGoogleMapView != null) {
                    mGoogleMapView.onDestroy();
                }
            }
        });
        //AMap amap = mAmapView.getMap();
        amap = mAmapView.getMap();
        amap.setOnCameraChangeListener(this);
        amap.setOnMapClickListener(this);
        mIsAmapDisplay = true;
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message message) {
            mAmapView.setVisibility(View.GONE);
            mContainerLayout.removeView(mAmapView);
            if (mAmapView != null) {
                mAmapView.onDestroy();
            }
        }
    };

    private void changeToGoogleMapView() {
        zoom = mAmapView.getMap().getCameraPosition().zoom;
        latitude = mAmapView.getMap().getCameraPosition().target.latitude;
        longitude = mAmapView.getMap().getCameraPosition().target.longitude;

        mapbtn.setText("To 高德地图");
        mIsAmapDisplay = false;
        mGoogleMapView = new com.google.android.gms.maps.MapView(this, new GoogleMapOptions()
                .camera(new com.google.android.gms.maps.model
                        .CameraPosition(new com.google.android.gms.maps.model.LatLng(latitude, longitude), zoom, 0, 0)));
        mGoogleMapView.onCreate(null);
        mGoogleMapView.onResume();
        mContainerLayout.addView(mGoogleMapView, mParams);
        mGoogleMapView.getMapAsync(this);
        handler.sendEmptyMessageDelayed(0, 500);
    }

    @Override
    public void onCameraChange(com.amap.api.maps.model.CameraPosition cameraPosition) {

    }

    @Override
    public void onCameraChangeFinish(com.amap.api.maps.model.CameraPosition cameraPosition) {
        longitude = cameraPosition.target.longitude;
        latitude = cameraPosition.target.latitude;
        zoom = cameraPosition.zoom;
        if (!isInArea(latitude, longitude) && mIsAmapDisplay && mIsAuto) {
            changeToGoogleMapView();
        }
    }

    private boolean isInArea(double latitude, double longtitude) {
        if ((latitude > 3.837031) && (latitude < 53.563624)
                && (longtitude < 135.095670) && (longtitude > 73.502355)) {
            return true;
        }
        return false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mAmapView != null) {
            mAmapView.onResume();
        }
        if (mGoogleMapView != null) {
            try {
                mGoogleMapView.onResume();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mAmapView != null) {
            mAmapView.onPause();
        }
        if (mGoogleMapView != null) {
            try {
                mGoogleMapView.onPause();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mAmapView != null) {
            mAmapView.onSaveInstanceState(outState);
        }
        if (mGoogleMapView != null) {
            try {
                mGoogleMapView.onSaveInstanceState(outState);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        destroyLocation();
        if (mAmapView != null) {
            mAmapView.onDestroy();
        }
        if (mGoogleMapView != null) {
            try {
                mGoogleMapView.onDestroy();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        this.googlemap = googleMap;
        if (googlemap != null) {
            googlemap.setOnCameraMoveListener(this);
        }
        addGoogleMarker();
        googlemap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(com.google.android.gms.maps.model.LatLng latLng) {
                longitude = latLng.longitude;
                latitude = latLng.latitude;
                getGooglePosition(latLng);
            }
        });
        UiSettings uiSettings = googlemap.getUiSettings();
        uiSettings.setAllGesturesEnabled(true);
        uiSettings.setMapToolbarEnabled(true);
        uiSettings.setZoomControlsEnabled(true);
        //uiSettings.setCompassEnabled(true);
    }

    private void getGooglePosition(com.google.android.gms.maps.model.LatLng latLng) {
        ApiUtil.init().getGooglePostion(latLng, new MyCallBack() {
            public void onSuccess(String result) {
                formatAddress = result;
                LogUtils.debug(TAG,"Google formatAddress ="+formatAddress);
                setCurrentPositionInfo();
                addGoogleMarker();
            }
        });
    }

    private void addGoogleMarker() {
        com.google.android.gms.maps.model.LatLng location = new com.google.android.gms.maps.model.LatLng(latitude, longitude);
        googlemap.addMarker(new com.google.android.gms.maps.model.MarkerOptions().position(location).title("当前坐标:"+longitude+","+latitude));
        googlemap.moveCamera(com.google.android.gms.maps.CameraUpdateFactory.newLatLng(location));
    }


    @Override
    public void onCameraMove() {
        CameraPosition cameraPosition=googlemap.getCameraPosition();
        longitude = cameraPosition.target.longitude;
        latitude = cameraPosition.target.latitude;
        zoom = cameraPosition.zoom;
        if (isInArea(latitude, longitude) && !mIsAmapDisplay && mIsAuto) {
            changeToAmapView();
        }
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null
                && aMapLocation.getErrorCode() == 0) {
            //longitude = aMapLocation.getLongitude();
            //latitude = aMapLocation.getLatitude();
            if (!aMapLocation.getCountry().equals("中国")){
                changeToGoogleMapView();
            } else {
                amap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude), 15));
            }
            //Toast.makeText(context,aMapLocation.getCountry(),Toast.LENGTH_LONG).show();
            mIsAuto = false;
            mcheckbtn.setChecked(false);
            //setCurrentPositionInfo();
        } else {
            String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
            LogUtils.debug("AmapErr", errText);
            Toast.makeText(context, errText, Toast.LENGTH_LONG).show();
        }
    }

    private void stopLocation(){
        // 停止定位
        mlocationClient.stopLocation();
    }

    private void destroyLocation(){
        if (null != mlocationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的,
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            mlocationClient.onDestroy();
            mlocationClient = null;
            mlocationClient = null;
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView.getId()==R.id.btn_auto_change) {
            mIsAuto = isChecked;
        }
    }
}