no.ntnu.idi.socialhitchhiking.map.MapActivityCreateOrEditRoute.java Source code

Java tutorial

Introduction

Here is the source code for no.ntnu.idi.socialhitchhiking.map.MapActivityCreateOrEditRoute.java

Source

/*******************************************************************************
 * @contributor(s): Freerider Team (Group 4, IT2901 Fall 2012, NTNU)
 * @contributor(s): Freerider Team 2 (Group 3, IT2901 Spring 2013, NTNU)
 * @version: 2.0
 * 
 * Copyright 2013 Freerider Team 2
 * 
 * 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 no.ntnu.idi.socialhitchhiking.map;

import java.io.IOException;
import java.util.ArrayList;

import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;

import no.ntnu.idi.freerider.model.Journey;
import no.ntnu.idi.freerider.model.Location;
import no.ntnu.idi.freerider.model.MapLocation;
import no.ntnu.idi.freerider.model.Route;
import no.ntnu.idi.freerider.protocol.Request;
import no.ntnu.idi.freerider.protocol.RequestType;
import no.ntnu.idi.freerider.protocol.Response;
import no.ntnu.idi.freerider.protocol.ResponseStatus;
import no.ntnu.idi.freerider.protocol.RouteRequest;
import no.ntnu.idi.freerider.protocol.RouteResponse;
import no.ntnu.idi.socialhitchhiking.R;
import no.ntnu.idi.socialhitchhiking.client.RequestTask;
import no.ntnu.idi.socialhitchhiking.utility.GpsHandler;

import org.apache.http.client.ClientProtocolException;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.res.Resources;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;

/**
 * The activity where a user creates or edits a {@link Route}. 
 */
public class MapActivityCreateOrEditRoute extends MapActivityAbstract {

    /**
     * The {@link FrameLayout} that contains the add destinationfield, clear/delete buttons
     */
    private FrameLayout AddDestFrameLayout;

    /**
     * The {@link LinearLayout} containing everything in the scrollview
     */
    private LinearLayout sclLayout;

    /**
     * ArrayList {@link ArrayList} of all the add destination fields
     */
    private ArrayList<InitDestFrame> acList;

    /**
     * Id for the add destination objects
     */
    private int id = 0;

    /**
     * Variable to contain the resources {@link Resources}
     */
    private Resources r;

    /**
     * The loading dialog {@link ProgressDialog} for the gps
     */
    private ProgressDialog loadingDialog;

    /**
     * This {@link CheckBox} determines whether a route should be saved or 
     * only be used as a "one time route".
     */
    private CheckBox chk_saveRoute;

    /**
     * The {@link AutoCompleteTextView} where the users writes where the route should end.
     */
    private AutoCompleteTextView acTo;

    /**
     * The {@link AutoCompleteTextView} where the users writes where the route should start.
     */
    private AutoCompleteTextView acFrom;

    /**
     * The one time {@link Route} that a {@link Journey} should be created 
     * from (When {@link #chk_saveRoute} is not checked).
     */
    private Route oneTimeRoute;

    /**
     * The {@link Route} that is saved, when {@link #chk_saveRoute} is checked.
     */
    private Route commonRouteSelected;

    /**
     * Switch for checking if the map is up to date
     */
    private boolean hasDrawn;

    /**
     * Constructor
     */
    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        acList = new ArrayList<InitDestFrame>();
        r = getResources();

        //Calls the initAutoComplete method, adding the autocomplete listeners to acTo and acFrom
        initAutocomplete();

        //Calls the initAddDestButton method, adding the driving through button
        initAddDestButton();

        //Sets hasDrawn to false
        hasDrawn = false;

        Bundle extras = getIntent().getExtras();

        if (extras != null) {
            inEditMode = extras.getBoolean("editMode");
            positionOfRoute = extras.getInt("routePosition");
        }

        //Hides the checkbox
        chk_saveRoute = (CheckBox) findViewById(R.id.checkBoxSave);
        chk_saveRoute.setVisibility(8);

        //Initialises the draw/next button
        final Button button = ((Button) findViewById(R.id.btnChooseRoute));

        //Adjustments to the gui if in editmode
        if (inEditMode) {
            chk_saveRoute.setVisibility(View.GONE);
            button.setText("Update the route");
            button.setLayoutParams(
                    new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
            fillFieldsInEdit();
            button.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    createInputDialog("Route", "Insert name of Route", false);
                }
            });
        } else {
            button.setText("Show on map");
            button.setEnabled(false);
        }

        //Initialises the textviews and the clear buttons
        final AutoCompleteTextView acFrom = (AutoCompleteTextView) findViewById(R.id.etGoingFrom);
        final AutoCompleteTextView acTo = (AutoCompleteTextView) findViewById(R.id.etGoingTo);
        ImageView bClearFrom = ((ImageView) findViewById(R.id.etGoingFromClearIcon));
        ImageView bClearTo = ((ImageView) findViewById(R.id.etGoingToClearIcon));

        //If map is drawn fill the textviews
        if (selectedRoute.getMapPoints().size() != 0) {
            fillFieldsOnClick();
        }

        /**
         * onClickListener on the clearButton on the acFrom field {@link OnClickListener()}
         */
        //Adds onClickListener to the clearbutton on the acFrom field
        bClearFrom.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                acFrom.setText("");
                button.setEnabled(false);
                button.setText("Show on Map");

            }

        });

        /**
         * onClickListener on the clearButton on the acTo field {@link OnClickListener}
         */
        //Adds onClickListener to the clearbutton on the acTo field
        bClearTo.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                acTo.setText("");
                button.setEnabled(false);
                button.setText("Show on Map");

            }

        });

        /**
         * TextWatcher to the acFrom {@link autoCompleteTextView} autoCompleteTextView {@link TextWatcher()}
         */
        //Adds a TextWatcher to the acFrom field, to update the draw/nextbutton, and its functionality
        acFrom.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                hasDrawn = false;
                if (checkFields() && selectedRoute.getMapPoints().size() > 1 && hasDrawn == true) {
                    button.setEnabled(true);
                    button.setText("Next");
                } else if (checkFields() && selectedRoute.getMapPoints().size() > 1 && hasDrawn == false) {
                    button.setEnabled(true);
                    button.setText("Show on Map");

                } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
                    button.setEnabled(true);
                    button.setText("Show on map");

                } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
                    button.setText("Show on map");
                    button.setEnabled(false);
                } else if (inEditMode) {

                } else {
                    button.setText("Show on map");
                    button.setEnabled(false);
                }

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub

            }

        });

        /**
         * TextWatcher to the acTo {@link autoCompleteTextView} autoCompleteTextView {@link TextWatcher()}
         */
        //Adds a TextWatcher to the acFrom field, to update the draw/nextbutton, and its functionality
        acTo.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                hasDrawn = false;
                if (checkFields() && selectedRoute.getMapPoints().size() > 2 && hasDrawn == true) {
                    button.setEnabled(true);
                    button.setText("Next");
                } else if (checkFields() && selectedRoute.getMapPoints().size() > 2 && hasDrawn == false) {
                    button.setEnabled(true);
                    button.setText("Show on Map");

                } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
                    button.setEnabled(true);
                    button.setText("Show on map");

                } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
                    button.setText("Show on map");
                    button.setEnabled(false);
                } else if (inEditMode) {

                } else {
                    button.setText("Show on map");
                    button.setEnabled(false);
                }

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub

            }

        });

        /**
         * onClickListener on the button(draw/next) {@link OnClickListener}
         */
        //adds the onclickListener to the draw/next button
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

                if (checkFields() && selectedRoute.getMapPoints().size() > 1 && hasDrawn == true) {
                    button.setText("Next");
                    createOneTimeJourney();

                } else if (checkFields() && selectedRoute.getMapPoints().size() > 1 && hasDrawn == false) {
                    mapView.getOverlays().clear();
                    createMap();
                    button.setText("Next");
                } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
                    mapView.getOverlays().clear();
                    createMap();
                    button.setText("Next");

                } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
                } else if (inEditMode) {
                    createInputDialog("Route", "Insert name of Route", false);
                    button.setText("Next");

                } else {

                }
            }
        });

    }

    /** checkFields()
     * checks if all the fields are filled, and if the content of the fields correspond with the points on the map
     * @return Boolean
     */
    protected boolean checkFields() {
        AutoCompleteTextView acFrom = (AutoCompleteTextView) findViewById(R.id.etGoingFrom);
        AutoCompleteTextView acTo = (AutoCompleteTextView) findViewById(R.id.etGoingTo);

        if ((acFrom.getText().toString().equals("") || acFrom.getText().toString().equals(""))
                && (acTo.getText().toString().equals("")
                        || acTo.getText().toString().equals("") && checkAddFields() == false)) {
            return false;
        } else if (acTo.getText().toString().equals("") || acTo.getText().toString().equals("")
                || checkAddFields() == false) {
            return false;
        } else if (acFrom.getText().toString().equals("") || acFrom.getText().toString().equals("")
                || checkAddFields() == false) {
            return false;
        } else {
            return true;
        }
    }

    /** checkAddFields()
     * helping method for the checkFields() method
     * checks the Driving Through fields
     * @return Boolean
     */
    protected boolean checkAddFields() {
        boolean check = true;
        for (int i = 0; i < acList.size(); i++) {
            if (acList.get(i).getAcField().getText().toString().equals("")
                    || acList.get(i).getAcField().getText().toString().length() == 0) {
                check = false;
            }
        }
        return check;
    }

    /** fillFieldsInEdit()
     * fills the fields if inEditmode
     */
    protected void fillFieldsInEdit() {
        AutoCompleteTextView acFrom = (AutoCompleteTextView) findViewById(R.id.etGoingFrom);
        AutoCompleteTextView acTo = (AutoCompleteTextView) findViewById(R.id.etGoingTo);

        acFrom.setText(selectedRoute.getMapPoints().get(0).getAddress());
        acTo.setText(selectedRoute.getMapPoints().get(selectedRoute.getMapPoints().size() - 1).getAddress());

        for (int i = 1; i < selectedRoute.getMapPoints().size() - 1; i++) {
            initDestFrameLayout();
            acList.get(i - 1).getAcField().setText(selectedRoute.getMapPoints().get(i).getAddress());
            setLayoutParams();
        }
    }

    /** setLayoutParams()
     *  when a Driving Through field is removed/added, repaint the Driving Through button
     */
    protected void setLayoutParams() {
        sclLayout.removeView(AddDestFrameLayout);
        initAddDestButton();
    }

    /** addToAcList
     * when Driving Through is clicked, adds the generated field {@link dest} to acList arrayList {@link ArrayList}
     * @param dest
     */
    private void addToAcList(InitDestFrame dest) {
        acList.add(dest);
    }

    /** removeFromAcList(int number)
     * deletes a Driving Through field, both from layout {@link autoCompleteTextView} and acList {@link ArrayList}
     * @param number      the id of the field beeing deleted
     */
    private void removeFromAcList(int number) {
        for (int i = 0; i < acList.size(); i++) {
            if (acList.get(i).getId() == number) {
                sclLayout.removeView(acList.get(i).getFrame());
                acList.remove(acList.get(i));
                break;
            }
        }
    }

    /** getStringList()
     * gets all the points from the fields and adds them to a String[] {@link String[]}
     * @return String[]
     */
    private String[] getStringList() {
        String[] acStringList;

        AutoCompleteTextView acV1 = (AutoCompleteTextView) findViewById(R.id.etGoingFrom);
        AutoCompleteTextView acV2 = (AutoCompleteTextView) findViewById(R.id.etGoingTo);

        ArrayList<InitDestFrame> mid = new ArrayList<InitDestFrame>();
        mid = getAcList();

        acStringList = new String[mid.size() + 2];

        //Adds the Going from location to the list

        acStringList[0] = acV1.getText().toString();

        //Adds all the locations between start/stop to the list
        for (int i = 1; i < mid.size() + 1; i++) {

            InitDestFrame etD1 = mid.get(i - 1);

            acStringList[i] = etD1.getAcField().getText().toString();
        }

        //Adds going To location to the list
        acStringList[mid.size() + 1] = acV2.getText().toString();
        return acStringList;
    }

    /** getAcList()
     * getter for the acList {@link ArrayList}
     * @return
     */
    //Get/return the acArray
    public ArrayList<InitDestFrame> getAcList() {
        return acList;
    }

    /** dipToPx(int dip)
     * translates dip to px
     * @param dip
     * @return px
     */
    public int dipToPx(int dip) {
        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, r.getDisplayMetrics());
        return (int) px;
    }

    /** initAddDestButton()
     * adds the Driving Through button
     */
    protected void initAddDestButton() {

        //Adds/enables the FrameLayout
        AddDestFrameLayout = new FrameLayout(this);
        AddDestFrameLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.WRAP_CONTENT, 80));
        AddDestFrameLayout.setEnabled(true);

        //Fills the Image Icon
        ImageView destAddIcon = new ImageView(this);
        FrameLayout.LayoutParams lliDestIcon = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                FrameLayout.LayoutParams.WRAP_CONTENT);
        lliDestIcon.setMargins(dipToPx(10), 0, 0, dipToPx(2));
        destAddIcon.setLayoutParams(lliDestIcon);
        destAddIcon.setPadding(0, dipToPx(5), 0, 0);
        destAddIcon.setImageResource(R.drawable.google_marker_thumb_mini_through);

        //Adds the imageicon to the framelayout/enables it 
        AddDestFrameLayout.addView(destAddIcon);

        //Fills/sets the text
        TextView destAddText = new TextView(this);
        FrameLayout.LayoutParams lliDest = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                FrameLayout.LayoutParams.WRAP_CONTENT);
        lliDest.setMargins(0, dipToPx(5), 0, 0);
        destAddText.setLayoutParams(lliDest);
        destAddText.setPadding(dipToPx(40), dipToPx(6), 0, 0);
        destAddText.setTextSize(15);
        destAddText.setText(R.string.mapViewAcField);

        //Adds the text to the framelayout
        AddDestFrameLayout.addView(destAddText);

        //Adds the framelayout to the linearlayout (in the scrollview)
        sclLayout = (LinearLayout) findViewById(R.id.sclLayout);
        sclLayout.addView(AddDestFrameLayout, sclLayout.getChildCount());

        final Button button = ((Button) findViewById(R.id.btnChooseRoute));

        //Adds a clicklistener to the frameLayout
        AddDestFrameLayout.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                //Adds a new destination field
                initDestFrameLayout();

                //Moves the button to the bottom
                setLayoutParams();

                if (checkFields() == false) {
                    button.setEnabled(false);
                    button.setText("Show on map");
                } else {
                    mapView.getOverlays().clear();
                    createMap();
                }
            }

        });
    }

    /** initDestFrameLayout()
     * adds a Driving Through field when the driving through button is clicked
     */
    //Adds a new destination field
    protected void initDestFrameLayout() {
        addToAcList(new InitDestFrame(id));
        id++;
    }

    /** InitDestFrame
     * object of the driving through field/buttons
     */
    public class InitDestFrame {

        private FrameLayout destFrameLayout;
        private AutoCompleteTextView acAdd;
        private ImageView destIcon;
        private final int id;
        private ImageView extIcon;
        private boolean checks;

        //Constructor
        public InitDestFrame(final int id) {
            this.destFrameLayout = new FrameLayout(MapActivityCreateOrEditRoute.this);
            this.acAdd = new AutoCompleteTextView(MapActivityCreateOrEditRoute.this);
            this.destIcon = new ImageView(MapActivityCreateOrEditRoute.this);
            this.extIcon = new ImageView(MapActivityCreateOrEditRoute.this);
            this.id = id;
            this.checks = true;

            //Adds/enables a new frameLayout
            destFrameLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT));

            //The acTextField, adds the autoCompleteTextView/sets it/enables it
            FrameLayout.LayoutParams lli = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            lli.setMargins(0, dipToPx(8), 0, 0);
            acAdd.setLayoutParams(lli);
            acAdd.setEms(10);
            acAdd.setHint(R.string.mapViewAcField);
            acAdd.setImeOptions(6);
            acAdd.setPadding(dipToPx(40), 0, dipToPx(55), 0);
            acAdd.setSingleLine();
            acAdd.setTextSize(15);
            acAdd.setId(id);
            acAdd.requestFocus();

            //Adds the AcTextField to the frameLayout
            destFrameLayout.addView(acAdd);

            //The Image Icon/sets it/enables it
            FrameLayout.LayoutParams lli2 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT, 16);
            lli2.setMargins(dipToPx(10), 0, 0, dipToPx(2));
            destIcon.setLayoutParams(lli2);
            destIcon.setPadding(0, dipToPx(5), 0, 0);
            destIcon.setImageResource(R.drawable.google_marker_thumb_mini_through);

            //adds the imageicon to the frameLayout
            destFrameLayout.addView(destIcon);

            final Button button = ((Button) findViewById(R.id.btnChooseRoute));

            //The exit icon for closing the entire frame
            extIcon.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT, 5));
            extIcon.setPadding(0, 12, 17, 0);
            extIcon.setImageResource(R.drawable.cross_dropoff);
            extIcon.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (acAdd.getText().toString().equals("")) {
                        //extIcon.setImageResource(R.drawable.cross_dropoff);
                        removeFromAcList(id);
                        if (checkFields()) {
                            button.setEnabled(true);
                            button.setText("Next");
                        } else {
                            button.setEnabled(false);
                            button.setText("Show on map");
                        }
                    } else {
                        //At det her funker er p hyde med tyngdekraft, universett og alt annet fantastisk!
                        extIcon.setImageResource(R.drawable.cross_dropoff);
                        acAdd.setText("");
                        extIcon.setImageResource(R.drawable.cross_dropoff);
                    }
                }
            });

            //adds the exit imageicon to the framelayout
            destFrameLayout.addView(extIcon);

            //adds the frameLayout to the linearLayout
            sclLayout.addView(destFrameLayout);

            //final Button button = ((Button)findViewById(R.id.btnChooseRoute));

            //adds the adapter for the textChangedListener
            acAdd.setAdapter(adapter);
            acAdd.addTextChangedListener(
                    new AutoCompleteTextWatcher(MapActivityCreateOrEditRoute.this, adapter, acAdd));

            //sets the done button on the keyboard
            acAdd.setOnEditorActionListener(new EditText.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                    if (actionId == EditorInfo.IME_ACTION_DONE) {
                        //
                        InputMethodManager imm = (InputMethodManager) getSystemService(
                                Context.INPUT_METHOD_SERVICE);
                        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
                        //
                        //hasDrawn = true;
                        if (checkFields() && selectedRoute.getMapPoints().size() > 2 && hasDrawn == true) {
                            createOneTimeJourney();
                            button.setEnabled(true);
                            button.setText("Next");
                            return true;
                        } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
                            mapView.getOverlays().clear();
                            createMap();
                            button.setEnabled(true);
                            button.setText("Next");
                            return true;
                        } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
                            button.setText("Show on map");
                            button.setEnabled(false);
                            return false;
                        } else if (inEditMode) {

                        } else {
                            button.setText("Show on map");
                            button.setEnabled(false);
                            return false;
                        }

                        return false;
                    } else {
                        return false;
                    }
                }
            });

            //Adds a TextWatcher to the textView, to update the draw/next button
            acAdd.addTextChangedListener(new TextWatcher() {

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    if (acAdd.getText().toString() != "") {
                        extIcon.setImageResource(R.drawable.speech_bubble_overlay_close);
                    } else {
                        extIcon.setImageResource(R.drawable.cross_dropoff);
                    }

                    hasDrawn = false;
                    if (checkFields() && selectedRoute.getMapPoints().size() > 1 && hasDrawn == true) {
                        button.setEnabled(true);
                        button.setText("Next");
                    } else if (checkFields() && selectedRoute.getMapPoints().size() > 1 && hasDrawn == false) {
                        button.setEnabled(true);
                        button.setText("Show on Map");

                    } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
                        button.setEnabled(true);
                        button.setText("Show on map");

                    } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
                        button.setText("Show on map");
                        button.setEnabled(false);
                    } else if (inEditMode) {

                    } else {
                        button.setText("Show on map");
                        button.setEnabled(false);
                    }

                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub

                }

            });
        }

        /*
         * Getters 
         */

        public AutoCompleteTextView getAcField() {
            return acAdd;
        }

        public int getId() {
            return id;
        }

        public FrameLayout getFrame() {
            return destFrameLayout;
        }
    }

    /** createMap()
     * draws the map
     */
    protected void createMap() {
        hasDrawn = true;
        drawPathOnMap(GeoHelper.getLocationList(getStringList()));
        generateName();
    }

    /** initContentView()
     * sets the contentView when the nextbutton is clicked
     */
    @Override
    protected void initContentView() {
        setContentView(R.layout.mapactivity_create_route);
    }

    /** initMapView()
     * initializes the map
     */
    @Override
    protected void initMapView() {
        mapView = (MapView) findViewById(R.id.map_view);
    }

    /** initProgressBar()
     *  initializes the progress bar
     */
    @Override
    protected void initProgressBar() {
        setProgressBar((ProgressBar) findViewById(R.id.progressBar));
    }

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

    /** createOneTimeJourney()
     * when the nextbutton is clicked, and all the requirements are fullfilled, creates a oneTimeJourney
     */
    private void createOneTimeJourney() {
        final Response res = chooseRoute();
        if (res.getStatus() == ResponseStatus.OK) {
            getApp().setSelectedRoute(oneTimeRoute);
            setTripOptions();
        } else
            createConfirmDialog(false, "Journey", "created", "");

    }

    /** setTripOptions()
     * sets the TripOptions
     */
    private void setTripOptions() {
        Intent intent = new Intent(MapActivityCreateOrEditRoute.this,
                no.ntnu.idi.socialhitchhiking.journey.TripOptions.class);
        startActivity(intent);
    }

    /**
     * Initialize the {@link AutoCompleteTextView}'s with an {@link ArrayAdapter} 
     * and a listener ({@link AutoCompleteTextWatcher}). The listener gets autocomplete 
     * data from the Google Places API and updates the ArrayAdapter with these.
     */
    private void initAutocomplete() {
        adapter = new ArrayAdapter<String>(this, R.layout.item_list);
        adapter.setNotifyOnChange(true);
        acFrom = (AutoCompleteTextView) findViewById(R.id.etGoingFrom);
        acFrom.setAdapter(adapter);
        acFrom.addTextChangedListener(new AutoCompleteTextWatcher(this, adapter, acFrom));
        acFrom.setThreshold(1);
        acTo = (AutoCompleteTextView) findViewById(R.id.etGoingTo);
        acTo.setAdapter(adapter);
        acTo.addTextChangedListener(new AutoCompleteTextWatcher(this, adapter, acTo));

        acTo.setOnEditorActionListener(new EditText.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
                final Button button = ((Button) findViewById(R.id.btnChooseRoute));
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    if (checkFields() && selectedRoute.getMapPoints().size() > 2 && hasDrawn == true) {
                        button.setEnabled(true);
                        button.setText("Next");
                        return true;
                    } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
                        mapView.getOverlays().clear();
                        createMap();
                        button.setEnabled(true);
                        button.setText("Next");
                        return true;
                    } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
                        button.setText("Show on map");
                        button.setEnabled(false);
                        return false;
                    } else {
                        button.setText("Show on map");
                        button.setEnabled(false);
                        return false;
                    }

                }
                return false;
            }

        });

    }

    /**
     * Sets the name of the {@link Route}, and calls {@link #chooseRoute()}.
     */
    private void setInputDialogResult(String name) {
        selectedRoute.setRouteName(name);
        chooseRoute();
    }

    /**
     * Takes the selected/drawn {@link Route} and chooses the correct 
     * {@link RouteRequest} to be sent (create route, update route or create ad hoc route).
     */
    private Response chooseRoute() {
        String action = "created";
        boolean saveRoute = chk_saveRoute.isChecked();
        MapRoute tempRoute = new MapRoute(selectedRoute, GeoHelper.getLocationList(getStringList()), false);
        selectedRoute.setRouteData(tempRoute.getRouteData());
        commonRouteSelected = getApp().getSelectedRoute();

        if (commonRouteSelected != null) {
            commonRouteSelected.setMapPoints(selectedRoute.getMapPoints());
            commonRouteSelected.setRouteData(selectedRoute.getRouteData());
            commonRouteSelected.setName(selectedRoute.getName());
        } else {
            translateRoute();
        }

        Request req;
        if (inEditMode) {
            req = new RouteRequest(RequestType.UPDATE_ROUTE, getUser(), commonRouteSelected);
            action = "updated";
        } else if (saveRoute)
            req = new RouteRequest(RequestType.CREATE_ROUTE, getUser(), commonRouteSelected);
        else {
            commonRouteSelected.setName(generateName());
            req = new RouteRequest(RequestType.CREATE_ROUTE, getUser(), commonRouteSelected);
        }

        try {

            Response res = RequestTask.sendRequest(req, getApp());
            if (res.getStatus() != ResponseStatus.OK) {
                if (inEditMode) {
                    String msg = res.getErrorMessage();
                    String error = "";
                    if (msg != null && msg.contains("alter") && msg.contains("active")) {
                        error = "\nCan't edit a route that's connected to an active journey";
                    }
                    createConfirmDialog(false, "Route", action, error);
                } else if (saveRoute)
                    createConfirmDialog(false, "Route", action, "");
                commonRouteSelected = getApp().getOldEditRoute();
                getApp().getRoutes().set(positionOfRoute, getApp().getOldEditRoute());
                return null;
            } else {
                if (saveRoute || inEditMode)
                    createConfirmDialog(true, "Route", action, "");

                RouteResponse r = (RouteResponse) res;
                if (!inEditMode) {
                    oneTimeRoute = r.getRoutes().get(0);
                    if (saveRoute)
                        getApp().getRoutes().add(oneTimeRoute);
                } else {
                    oneTimeRoute = r.getRoutes().get(0);
                    getApp().getRoutes().set(positionOfRoute, oneTimeRoute);
                }

                return res;

            }
        } catch (ClientProtocolException e) {
            if (saveRoute)
                createConfirmDialog(false, "Route", action, "");
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            if (saveRoute)
                createConfirmDialog(false, "Route", action, "");
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        return null;
    }

    /** generateName()
     * generates a name for the route {@link Route} based on the points on the map
     * @return name
     */
    private String generateName() {

        String name = "";
        String midLong = "";
        String midShort = "";

        for (int i = 0; i < selectedRoute.getMapPoints().size(); i++) {
            midLong = selectedRoute.getMapPoints().get(i).getAddress();
            for (int j = 0; j < midLong.length(); j++) {
                if (midLong.charAt(j) == ',') {
                    break;
                } else {
                    midShort += midLong.charAt(j);
                }
            }
            name += midShort;
            name += ' ';
            name += '-';
            name += ' ';
            midShort = "";
        }

        return name;
    }

    /** onGpsClicked
     * activates the gps when gps button is clicked, and fills the acFrom field with the gps info
     * @param view
     */
    public void onGpsClicked(View view) {
        final GpsHandler gps = new GpsHandler(this);
        if (!gps.gpsEnabled()) {
            Toast.makeText(this, "GPS is not activated", Toast.LENGTH_LONG).show();
            return;
        }

        loadingDialog = ProgressDialog.show(this, "Locating", "Finding your location");
        loadingDialog.setCancelable(true);
        loadingDialog.setOnCancelListener(new OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                gps.abortGPS();
                loadingDialog.dismiss();
            }
        });
        gps.findLocation();
        new Thread() {
            public void run() {
                try {
                    sleep(60000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                loadingDialog.dismiss();
                gps.abortGPS();
            }
        }.start();

    }

    /** gotLocation(andoid.location.Location location)
     * helping method for the gpsClicked method
     * fills the acFrom {@link AutoCompleteTextView} field with the gps information
     * @param location
     */
    public void gotLocation(android.location.Location location) {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        try {
            List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
            acFrom.setText(addresses.get(0).getAddressLine(0) + ", " + addresses.get(0).getAddressLine(1));
        } catch (IOException e) {
            Toast.makeText(this, "Problem with GPS, try restarting your device", Toast.LENGTH_LONG).show();
        }
        loadingDialog.dismiss();
    }

    private void translateRoute() {
        List<Location> list = selectedRoute.getRouteData();

        String name = "";
        int serial = -1;

        if (chk_saveRoute.isChecked() || inEditMode) {
            name = selectedRoute.getRouteName();
            serial = selectedRoute.getSerial();
        }

        commonRouteSelected = new Route(getUser(), name, list, serial);
        commonRouteSelected.setMapPoints(selectedRoute.getMapPoints());

    }

    private void createConfirmDialog(boolean flag, String type, String action, String error) {
        if (flag) {
            new AlertDialog.Builder(this).setTitle("Confirmed").setMessage(type + " " + action + "!")
                    .setNegativeButton("Close", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    }).show();
        } else {
            new AlertDialog.Builder(this).setTitle("ERROR").setMessage(type + " not " + action + "!" + error)
                    .setNegativeButton("Close", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) {
                        }

                    }).show();
        }
    }

    @Override
    /**
     * Creates a menu from the xml_mapmenu.xml file.
     * 
     */
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.xml_mapmenu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    /**
     * Defines what happens when you click a {@link MenuItem}
     */
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.mapmenu_add) {
            addPointDialog();
            return true;
        }

        else if (item.getItemId() == R.id.mapmenu_order) {
            changeOrder();
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }

    }

    /**
     * Starts an activity where the user can change the order of (or delete) the map points.
     */
    private void changeOrder() {
        if (getSelectedRoute() == null || getSelectedRoute().getMapPoints() == null
                || getSelectedRoute().getMapPoints().size() == 0) {
            Toast toast = Toast.makeText(this, "You must add some points first", Toast.LENGTH_LONG);
            toast.setGravity(Gravity.BOTTOM, toast.getXOffset() / 2, toast.getYOffset() / 2);
            toast.show();
            return;
        }
        Intent dragAndDropIntent = new Intent(this,
                no.ntnu.idi.socialhitchhiking.map.draganddrop.DragAndDropListActivity.class);
        getApp().setSelectedMapRoute(selectedRoute);
        dragAndDropIntent.putExtra("type", "changeOrder");
        dragAndDropIntent.putExtra("editMode", inEditMode);
        dragAndDropIntent.putExtra("routePosition", positionOfRoute);
        startActivity(dragAndDropIntent);
        finish();
    }

    /** clearMap()
     * Initializes a new map
     */
    private void clearMap() {
        Intent newClearedMap = new Intent(this,
                no.ntnu.idi.socialhitchhiking.map.MapActivityCreateOrEditRoute.class);
        newClearedMap.putExtra("latitudeE6", mapView.getMapCenter().getLatitudeE6());
        newClearedMap.putExtra("longitudeE6", mapView.getMapCenter().getLongitudeE6());
        newClearedMap.putExtra("zoomLevel", mapView.getZoomLevel());
        newClearedMap.putExtra("clear", true);
        startActivity(newClearedMap);
        finish();
    }

    /** addPointDialog
     * Initializes a inputdialog, for adding a driving through point
     */
    private void addPointDialog() {
        createInputDialog("Add point", "Add a point by writing the address", true);
    }

    /** createInputDialog
     * Builds a dialog
     * @param title
     * @param msg
     * @param autoComplete
     */
    private void createInputDialog(String title, String msg, boolean autoComplete) {
        SocialHitchhikingDialog alert = new SocialHitchhikingDialog(title, msg, autoComplete);
        alert.show();
    }

    private class SocialHitchhikingDialog extends AlertDialog {
        private EditText input;
        private MapActivityCreateOrEditRoute activity;

        public SocialHitchhikingDialog(String title, String msg, boolean autoComplete) {
            super(MapActivityCreateOrEditRoute.this);
            activity = MapActivityCreateOrEditRoute.this;
            setTitle(title);
            setMessage(msg);

            if (autoComplete) {
                input = new AutoCompleteTextView(getContext());
                adapter = new ArrayAdapter<String>(getContext(), R.layout.item_list);
                adapter.setNotifyOnChange(true);
                input.addTextChangedListener(new AutoCompleteTextWatcher(activity, adapter, acTo));
                android.content.DialogInterface.OnClickListener listener = new android.content.DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == DialogInterface.BUTTON_POSITIVE) {
                            String value = input.getText().toString();
                            if (value == "" || value.length() == 0) {
                                makeToast("You have to write an address");
                            } else {
                                InputMethodManager imm = (InputMethodManager) activity
                                        .getSystemService(Context.INPUT_METHOD_SERVICE);
                                imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                                MapLocation mapLocation = GeoHelper.getLocation(value);
                                activity.addPoint(mapLocation);
                            }
                        } else if (which == DialogInterface.BUTTON_NEGATIVE) {

                        }
                    }
                };
                setButton(DialogInterface.BUTTON_POSITIVE, "OK", listener);
                setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", listener);
            } else {
                input = new EditText(activity);
                setButton(DialogInterface.BUTTON_POSITIVE, "OK", new NameInputClickListener(input));
                setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new NameInputClickListener(input));
                if (inEditMode) {
                    input.setText(selectedRoute.getRouteName());
                }
            }

            setView(input);
        }
    }

    private class NameInputClickListener implements android.content.DialogInterface.OnClickListener {
        private MapActivityCreateOrEditRoute activity;
        private EditText input;

        public NameInputClickListener(EditText input) {
            this.activity = MapActivityCreateOrEditRoute.this;
            this.input = input;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (which == DialogInterface.BUTTON_POSITIVE) {
                String value = input.getText().toString();
                if (value == "" || value.length() == 0)
                    activity.createInputDialog("ERROR", "Name can't be empty", false);
                else {
                    InputMethodManager imm = (InputMethodManager) activity
                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                    activity.setInputDialogResult(value);
                }
            } else if (which == DialogInterface.BUTTON_NEGATIVE) {
                activity.makeToast("The route was not saved");
            }
        }
    }

    /** fillFieldsOnClick()
     * fills the fields if the map is already drawn, or an error occures with the corresponding fields
     */
    protected void fillFieldsOnClick() {

        final Button button = ((Button) findViewById(R.id.btnChooseRoute));
        AutoCompleteTextView acFrom = (AutoCompleteTextView) findViewById(R.id.etGoingFrom);
        AutoCompleteTextView acTo = (AutoCompleteTextView) findViewById(R.id.etGoingTo);
        acFrom.setText("");
        acTo.setText("");
        int aSize = selectedRoute.getMapPoints().size();

        //Adds the first point to the going from field
        if (aSize == 1) {
            acFrom.setText(selectedRoute.getMapPoints().get(0).getAddress().toString());

        } else if (aSize == 2) {
            acFrom.setText(selectedRoute.getMapPoints().get(0).getAddress().toString());

            acTo.setText(selectedRoute.getMapPoints().get(selectedRoute.getMapPoints().size() - 1).getAddress()
                    .toString());

        } else if (aSize >= 3) {
            acFrom.setText(selectedRoute.getMapPoints().get(0).getAddress().toString());
            acTo.setText(selectedRoute.getMapPoints().get(selectedRoute.getMapPoints().size() - 1).getAddress()
                    .toString());

            while (acList.size() >= 1) {
                int id = acList.get(0).getId();
                removeFromAcList(id);
                setLayoutParams();
            }

            for (int i = 1; i < selectedRoute.getMapPoints().size() - 1; i++) {
                initDestFrameLayout();
                acList.get(i - 1).getAcField().setText(selectedRoute.getMapPoints().get(i).getAddress().toString());

                setLayoutParams();

            }
        }
        if (checkFields() && selectedRoute.getMapPoints().size() > 1) {
            button.setEnabled(true);
            button.setText("Next");
            hasDrawn = true;
        } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
            button.setEnabled(true);
            button.setText("Show on map");
        } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
        } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
            button.setText("Show on map");
            button.setEnabled(false);
        }
        mapView.invalidate();
    }

    /** clearMapOnClick(View view)
     * removes all the points on the map, and updates the draw/next button
     * @param view
     */
    public void clearMapOnClick(View view) {
        mapView.getOverlays().clear();
        final Button button = ((Button) findViewById(R.id.btnChooseRoute));
        mapView.invalidate();
        MapRoute midRoute = new MapRoute();
        selectedRoute = midRoute;

        if (checkFields() && selectedRoute.getMapPoints().size() > 1) {
            button.setEnabled(true);
            button.setText("Next");
        } else if (checkFields() && selectedRoute.getMapPoints().size() == 0) {
            button.setEnabled(true);
            button.setText("Show on map");
        } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
        } else if (checkFields() == false && selectedRoute.getMapPoints().size() == 0) {
            button.setText("Show on map");
            button.setEnabled(false);
        }

    }

    /**
     * When the user long presses on the screen, a dialog should pop up
     * where he/she is asked to add the point/address to the route.
     */

    @Override
    public void onLongPress(MotionEvent e) {

    }

    /** onSingleTapUp(MotionEvent e)
     * updates the {@link AutoCompleteTextView} fields on map movement
     */
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        GeoPoint gp = mapView.getProjection().fromPixels((int) e.getX(), (int) e.getY());
        MapLocation mapLocation = (MapLocation) GeoHelper.getLocation(gp);

        addPoint(mapLocation);
        fillFieldsOnClick();
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        fillFieldsOnClick();
        return false;
    }

}