/*
 * Copyright (c) 2016 NECTEC
 *   National Electronics and Computer Technology Center, Thailand
 *
 * 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 th.or.nectec.marlo;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import th.or.nectec.marlo.model.PolygonData;
import th.or.nectec.marlo.option.DefaultPolygonMarkerOptionFactory;
import th.or.nectec.marlo.option.DefaultPolygonOptionFactory;
import th.or.nectec.marlo.option.PolygonOptionFactory;

import java.util.List;
import java.util.Stack;

public class PolygonMarloFragment extends MarloFragment {

    private final Stack<PolygonData> multiPolygon = new Stack<>();
    private final PolygonData singlePolygon = new PolygonData();

    private Mode mode = Mode.SINGLE;
    private PolygonOptionFactory polygonOptionFactory;

    public PolygonMarloFragment() {
        super();
        markerOptionFactory = new DefaultPolygonMarkerOptionFactory();
        polygonOptionFactory = new DefaultPolygonOptionFactory();
    }

    public static PolygonMarloFragment newInstance(Mode mode) {
        PolygonMarloFragment fragment = new PolygonMarloFragment();
        fragment.mode = mode;
        return fragment;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    public void setPolygonOptionFactory(PolygonOptionFactory polygonOptionFactory) {
        this.polygonOptionFactory = polygonOptionFactory;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        ViewUtils.addPolygonToolsMenu(this);
        findViewBy(R.id.marlo_boundary).setVisibility(mode == Mode.MULTI ? View.VISIBLE : View.GONE);
        multiPolygon.push(new PolygonData());
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.marlo_hole) {
            getActivePolygonData().newHole();
            getActivePolygonData().setCurrentState(PolygonData.State.HOLE);
        } else if (view.getId() == R.id.marlo_boundary) {
            multiPolygon.push(new PolygonData());
            getActivePolygonData().setCurrentState(PolygonData.State.BOUNDARY);
        } else if (view.getId() == R.id.marlo_undo) {
            undo();
        } else {
            super.onClick(view);
        }
    }

    public PolygonData getActivePolygonData() {
        return mode == Mode.SINGLE ? singlePolygon : multiPolygon.peek();
    }

    @Override
    public void mark(LatLng markPoint) {
        SoundUtility.play(getContext(), R.raw.thumpsoundeffect);

        Marker marker = googleMap.addMarker(markerOptionFactory.build(this, markPoint));
        PolygonData activePolygon = getActivePolygonData();
        boolean success = activePolygon.addMarker(marker);
        if (!success) {
            onMarkHoleOutBound(markPoint, activePolygon.getPolygon().getPoints());
            marker.remove();
        }

        PolygonDrawUtils.createPolygon(googleMap, activePolygon, polygonOptionFactory.build(this));
    }

    protected void onMarkHoleOutBound(LatLng target, List<LatLng> points) {
        Toast.makeText(getActivity(), "Out of polygon boundary ", Toast.LENGTH_SHORT).show();
    }

    public boolean undo() {
        PolygonData polygonData = getActivePolygonData();
        if (polygonData.isEmpty()) {
            return false;
        }
        boolean removed = polygonData.removeLastMarker();

        if (removed && polygonData.isEmpty() && mode == Mode.MULTI && multiPolygon.size() > 1) {
            multiPolygon.pop();
        }

        PolygonDrawUtils.createPolygon(googleMap, polygonData, polygonOptionFactory.build(this));
        return true;
    }

    public Stack<PolygonData> getPolygons() {
        return multiPolygon;
    }

    public PolygonData getPolygon() {
        return singlePolygon;
    }

    public PolygonData.State getDrawingState() {
        return getActivePolygonData().getCurrentState();
    }

    public enum Mode {
        SINGLE,
        MULTI
    }
}

@@ -760,24 +760,149 @@
 dget.Toast;%0A
+import com.google.android.gms.maps.model.BitmapDescriptor;%0Aimport com.google.android.gms.maps.model.BitmapDescriptorFactory;%0A
 import com.g
@@ -938,16 +938,16 @@
 LatLng;%0A
-
 import c
@@ -1453,25 +1453,119 @@
 ygonData();%0A
+    private BitmapDescriptor activeMarkerIcon;%0A    private BitmapDescriptor passiveMarkerIcon;
 %0A
-
     private 
@@ -1831,24 +1831,25 @@
 nFactory();%0A
+%0A
     %7D%0A%0A    p
@@ -2384,24 +2384,225 @@
 nceState);%0A%0A
+        activeMarkerIcon = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED);%0A        passiveMarkerIcon = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN);%0A%0A
         View
@@ -3729,32 +3729,86 @@
 ePolygonData();%0A
+        setUpdateIconToLastMarker(passiveMarkerIcon);%0A
         boolean 
@@ -3988,33 +3988,32 @@
 ve();%0A        %7D%0A
-%0A
         PolygonD
@@ -4496,16 +4496,69 @@
 arker();
+%0A        setUpdateIconToLastMarker(activeMarkerIcon);
 %0A%0A      
@@ -4785,24 +4785,24 @@
 ild(this));%0A
-
         retu
@@ -4809,32 +4809,466 @@
 rn true;%0A    %7D%0A%0A
+    private void setUpdateIconToLastMarker(BitmapDescriptor icon) %7B%0A        Marker lastMarker = getActivePolygonData().getLastMarker();%0A        if (lastMarker != null) %7B%0A            lastMarker.setIcon(icon);%0A        %7D else if (multiPolygon.size() %3E 1) %7B%0A            PolygonData topPolygon = multiPolygon.pop();%0A            multiPolygon.peek().getLastMarker().setIcon(icon);%0A            multiPolygon.push(topPolygon);%0A        %7D%0A    %7D%0A%0A
     public Stack

support active and passive marker style