public class SlidingTabLayout extends HorizontalScrollView {
    /**
     * Allows complete control over the colors drawn in the tab layout. Set with
     * {@link #setCustomTabColorizer(TabColorizer)}.
     */
    public interface TabColorizer {

        /**
         * @return return the color of the indicator used when {@code position} is selected.
         */
        int getIndicatorColor(int position);

    }

    private static final int TITLE_OFFSET_DIPS = 24;
    private static final int TAB_VIEW_PADDING_DIPS = 16;
    private static final int TAB_VIEW_TEXT_SIZE_SP = 12;

    private int mTitleOffset;

    private int mTabViewLayoutId;
    private int mTabViewTextViewId;
    private boolean mDistributeEvenly;

    private ViewPager mViewPager;
    private SparseArray<String> mContentDescriptions = new SparseArray<String>();
    private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;

    private final SlidingTabStrip mTabStrip;

    public SlidingTabLayout(Context context) {
        this(context, null);
    }

    public SlidingTabLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // Disable the Scroll Bar
        setHorizontalScrollBarEnabled(false);
        // Make sure that the Tab Strips fills this View
        setFillViewport(true);

        mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);

        mTabStrip = new SlidingTabStrip(context);
        addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    }

    /**
     * Set the custom {@link TabColorizer} to be used.
     * <p>
     * If you only require simple custmisation then you can use
     * {@link #setSelectedIndicatorColors(int...)} to achieve
     * similar effects.
     */
    public void setCustomTabColorizer(TabColorizer tabColorizer) {
        mTabStrip.setCustomTabColorizer(tabColorizer);
    }

    public void setDistributeEvenly(boolean distributeEvenly) {
        mDistributeEvenly = distributeEvenly;
    }

    /**
     * Sets the colors to be used for indicating the selected tab. These colors are treated as a
     * circular array. Providing one color will mean that all tabs are indicated with the same color.
     */
    public void setSelectedIndicatorColors(int... colors) {
        mTabStrip.setSelectedIndicatorColors(colors);
    }

    /**
     * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
     * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
     * that the layout can update it's scroll position correctly.
     *
     * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
     */
    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
        mViewPagerPageChangeListener = listener;
    }

    /**
     * Set the custom layout to be inflated for the tab views.
     *
     * @param layoutResId Layout id to be inflated
     * @param textViewId  id of the {@link TextView} in the inflated view
     */
    public void setCustomTabView(int layoutResId, int textViewId) {
        mTabViewLayoutId = layoutResId;
        mTabViewTextViewId = textViewId;
    }

    /**
     * Sets the associated view pager. Note that the assumption here is that the pager content
     * (number of tabs and tab titles) does not change after this call has been made.
     */
    public void setViewPager(ViewPager viewPager) {
        mTabStrip.removeAllViews();

        mViewPager = viewPager;
        if (viewPager != null) {
            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
            populateTabStrip();
        }
    }

    /**
     * Create a default view to be used for tabs. This is called if a custom tab view is not set via
     * {@link #setCustomTabView(int, int)}.
     */
    protected TextView createDefaultTabView(Context context) {
        TextView textView = new TextView(context);
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
        textView.setTypeface(Typeface.DEFAULT_BOLD);
        textView.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        TypedValue outValue = new TypedValue();
        getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
                outValue, true);
        textView.setBackgroundResource(outValue.resourceId);
        textView.setAllCaps(true);

        int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
        textView.setPadding(padding, padding, padding, padding);

        return textView;
    }

    private void populateTabStrip() {
        final PagerAdapter adapter = mViewPager.getAdapter();
        final View.OnClickListener tabClickListener = new TabClickListener();

        for (int i = 0; i < adapter.getCount(); i++) {
            View tabView = null;
            TextView tabTitleView = null;

            if (mTabViewLayoutId != 0) {
                // If there is a custom tab view layout id set, try and inflate it
                tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
                        false);
                tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
            }

            if (tabView == null) {
                tabView = createDefaultTabView(getContext());
            }

            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
                tabTitleView = (TextView) tabView;
            }

            if (mDistributeEvenly) {
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
                lp.width = 0;
                lp.weight = 1;
            }

            tabTitleView.setText(adapter.getPageTitle(i));
            tabView.setOnClickListener(tabClickListener);
            String desc = mContentDescriptions.get(i, null);
            if (desc != null) {
                tabView.setContentDescription(desc);
            }

            mTabStrip.addView(tabView);
            if (i == mViewPager.getCurrentItem()) {
                tabView.setSelected(true);
            }
        }
    }

    public void setContentDescription(int i, String desc) {
        mContentDescriptions.put(i, desc);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (mViewPager != null) {
            scrollToTab(mViewPager.getCurrentItem(), 0);
        }
    }

    private void scrollToTab(int tabIndex, int positionOffset) {
        final int tabStripChildCount = mTabStrip.getChildCount();
        if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
            return;
        }

        View selectedChild = mTabStrip.getChildAt(tabIndex);
        if (selectedChild != null) {
            int targetScrollX = selectedChild.getLeft() + positionOffset;

            if (tabIndex > 0 || positionOffset > 0) {
                // If we're not at the first child and are mid-scroll, make sure we obey the offset
                targetScrollX -= mTitleOffset;
            }

            scrollTo(targetScrollX, 0);
        }
    }

    private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
        private int mScrollState;

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            int tabStripChildCount = mTabStrip.getChildCount();
            if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
                return;
            }

            mTabStrip.onViewPagerPageChanged(position, positionOffset);

            View selectedTitle = mTabStrip.getChildAt(position);
            int extraOffset = (selectedTitle != null)
                    ? (int) (positionOffset * selectedTitle.getWidth())
                    : 0;
            scrollToTab(position, extraOffset);

            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
                        positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            mScrollState = state;

            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageScrollStateChanged(state);
            }
        }

        @Override
        public void onPageSelected(int position) {
            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
                mTabStrip.onViewPagerPageChanged(position, 0f);
                scrollToTab(position, 0);
            }
            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                mTabStrip.getChildAt(i).setSelected(position == i);
            }
            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageSelected(position);
            }
        }

    }

    private class TabClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                if (v == mTabStrip.getChildAt(i)) {
                    mViewPager.setCurrentItem(i);
                    return;
                }
            }
        }
    }

} public class URLBuilder {
    public static String getMovieWithIdURL(int movieId) {
        String url =
                TMDB_API_URL_BASE +
                        TMDB_API_URL_MOVIE +
                        Integer.toString(movieId) +
                        "?" +
                        TMDB_API_URL_API +
                        TMDB_API_KEY;
        return url;
    }

    public static String getMovieSearchURL(String movieTitle) throws UnsupportedEncodingException {
        String url =
                TMDB_API_URL_BASE +
                        TMDB_API_URL_SEARCH +
                        "?" +
                        TMDB_API_URL_API +
                        TMDB_API_KEY +
                        "&" +
                        TMDB_API_URL_QUERY +
                        URLEncoder.encode(movieTitle, "UTF-8");
        return url;
    }

    public static String getImageURL(String path) {
        String url =
                TMDB_IMAGE_BASE_URL +
                        TMDB_POSTER_SIZE_DEFAULT +
                        path;
        return url;
    }

    public static String getUpcomingMoviesURL() {
        String url =
                TMDB_API_URL_BASE +
                        TMDB_API_URL_MOVIE +
                        TMDB_API_URL_UPCOMING +
                        "?" +
                        TMDB_API_URL_API +
                        TMDB_API_KEY;
        return url;
    }

    public static String getOmdbResultWithIdURL(String imdbId) {
        String url =
                OMDB_BASE_URL +
                        "?" +
                        OMDB_IMDB_ID +
                        imdbId +
                        "&" +
                        OMDB_PLOT +
                        "&" +
                        OMDB_R;
        return url;
    }

    public static String getRottenTomatoesResultWithIdURL(String imdbId) {
        StringBuilder stringBuilder = new StringBuilder(imdbId.length() - 2);
        stringBuilder.append(imdbId, 2, imdbId.length());
        String trimmedImdbId = stringBuilder.toString();
        String url =
                ROTTEN_TOMATOES_BASE_URL +
                        "?" +
                        ROTTEN_TOMATOES_API +
                        ROTTEN_TOMATOES_API_KEY +
                        "&" +
                        ROTTEN_TOMATOES_TYPE_IMDB +
                        "&" +
                        ROTTEN_TOMATOES_IMDB_ID +
                        trimmedImdbId;
        return url;
    }


} public class AnimationUtils {
    public static void scaleXY(RecyclerView.ViewHolder holder) {
        holder.itemView.setScaleX(0);
        holder.itemView.setScaleY(0);

        PropertyValuesHolder propx = PropertyValuesHolder.ofFloat("scaleX", 1);
        PropertyValuesHolder propy = PropertyValuesHolder.ofFloat("scaleY", 1);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(holder.itemView, propx, propy);


        animator.setDuration(800);
        animator.start();
    }

    public static void scaleX(RecyclerView.ViewHolder holder) {
        holder.itemView.setScaleX(0);

        PropertyValuesHolder propx = PropertyValuesHolder.ofFloat("scaleX", 1);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(holder.itemView, propx);


        animator.setDuration(800);
        animator.start();
    }

    public static void scaleY(RecyclerView.ViewHolder holder) {
        holder.itemView.setScaleY(0);

        PropertyValuesHolder propy = PropertyValuesHolder.ofFloat("scaleY", 1);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(holder.itemView, propy);

        animator.setDuration(800);
        animator.start();
    }

    public static void animate(RecyclerView.ViewHolder holder, boolean goesDown) {

        ObjectAnimator animatorTranslateY = ObjectAnimator.ofFloat(holder.itemView, "translationY", goesDown == true ? 300 : -300, 0);
        animatorTranslateY.setDuration(500);
        animatorTranslateY.start();


    }

    public static void animateToolbar(View containerToolbar) {


    }

    /*
    * Makes fade animation for Relativelayout
    * description is view, which we want to animate
    * isShow is flag for showing or hiding
    * */
    public static void PopupAnimate(RelativeLayout description, boolean isShowing) {
        if (isShowing == true) {
            YoYo.with(Techniques.FadeIn).duration(500).playOn(description);
        } else {
            YoYo.with(Techniques.FadeOut).duration(500).playOn(description);
        }
    }

} public class FollowingCommentsFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters


    private ParseUser currentUser;
    private String currentUsername;
    private int movieId;
    private RecyclerView followingCommentsRecyclerView;
    private FollowingCommentsAdapter followingCommentsAdapter;
    private TopCommentsAdapter topCommentsAdapter;
    private VolleySingleton volleySingleton;
    private RequestQueue requestQueue;

    private ArrayList<String> mFollowedUsers = new ArrayList<>();
    protected static List<ParseObject> myWubbles;


    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param2 Parameter 2.
     * @return A new instance of fragment FollowingFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static FollowingCommentsFragment newInstance(int param2) {
        FollowingCommentsFragment fragment = new FollowingCommentsFragment();
        Bundle args = new Bundle();

        args.putInt(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    public FollowingCommentsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            movieId = getArguments().getInt(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_following_comments, container, false);

        volleySingleton = VolleySingleton.getInstance();
        requestQueue = volleySingleton.getRequestQueue();

        currentUser = ParseUser.getCurrentUser();
        currentUsername = currentUser.getUsername();


        followingCommentsRecyclerView = (RecyclerView) view.findViewById(R.id.followingCommentsRecyclerView);
        followingCommentsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        FollowingCommentsAdapter emptyAdapter = new FollowingCommentsAdapter(getActivity());
        followingCommentsRecyclerView.setAdapter(emptyAdapter);


        if (currentUser != null) {
            ParseQuery<ParseObject> userQuery = new ParseQuery<ParseObject>("FollowRelations");
            userQuery.whereEqualTo("Username", currentUser.getUsername());


            userQuery.getFirstInBackground(new GetCallback<ParseObject>() {
                @Override
                public void done(ParseObject parseObject, ParseException e) {
                    if (e == null) {

                        mFollowedUsers = (ArrayList<String>) parseObject.get("Following");
                        if (mFollowedUsers != null && mFollowedUsers.size() > 0) {

                            ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Wubbles");
                            query.whereContainedIn("User", mFollowedUsers);
                            query.whereEqualTo("movieId", movieId);
                            query.orderByDescending("createdAt");

                            query.findInBackground(new FindCallback<ParseObject>() {
                                @Override
                                public void done(List<ParseObject> wubbles, ParseException e) {
                                    if (e == null) {

                                        //mSpinner.setVisibility(View.GONE);
                                        myWubbles = wubbles;
                                        if (myWubbles != null && myWubbles.size() > 0) {


                                            followingCommentsAdapter = new FollowingCommentsAdapter(getActivity(), myWubbles, mFollowedUsers, movieId);
                                            followingCommentsRecyclerView.setAdapter(followingCommentsAdapter);

                                            //mTextView.setVisibility(View.GONE);
                                            //mSpinner.setVisibility(View.GONE);
                                            //feedRecyclerView.setVisibility(View.VISIBLE);
                                        } else {
                                            //mTextView.setVisibility(View.VISIBLE);
                                            //mSpinner.setVisibility(View.GONE);
                                        }


                                    } else {
                                        // handle problems here
                                    }
                                }
                            });
                        }
                    }
                }
            });
        }

        return view;
    }


} public class TopCommentsFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";


    // TODO: Rename and change types of parameters


    private int movieIdParam;


    private ParseUser currentUser;
    private String currentUsername;
    private int movieId;
    private RecyclerView topCommentsRecyclerView;
    private TopCommentsAdapter topCommentsAdapter;

    private VolleySingleton volleySingleton;
    private RequestQueue requestQueue;

    private ArrayList<String> mFollowedUsers = new ArrayList<>();
    protected static List<ParseObject> myWubbles;

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @return A new instance of fragment TopCommentsFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static TopCommentsFragment newInstance(int param1) {
        TopCommentsFragment fragment = new TopCommentsFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PARAM1, param1);

        fragment.setArguments(args);
        return fragment;
    }

    public TopCommentsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            movieId = getArguments().getInt(ARG_PARAM1);

        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_top_comments, container, false);

        volleySingleton = VolleySingleton.getInstance();
        requestQueue = volleySingleton.getRequestQueue();

        currentUser = ParseUser.getCurrentUser();
        currentUsername = currentUser.getUsername();


        topCommentsRecyclerView = (RecyclerView) view.findViewById(R.id.topCommentsRecyclerView);
        topCommentsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        TopCommentsAdapter emptyAdapter = new TopCommentsAdapter(getActivity());
        topCommentsRecyclerView.setAdapter(emptyAdapter);


        if (currentUser != null) {
            ParseQuery<ParseObject> userQuery = new ParseQuery<ParseObject>("FollowRelations");
            userQuery.whereEqualTo("Username", currentUser.getUsername());


            ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Wubbles");

            query.whereEqualTo("movieId", movieId);
            query.orderByDescending("createdAt");

            query.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> wubbles, ParseException e) {
                    if (e == null) {

                        //mSpinner.setVisibility(View.GONE);

                        Comparator<ParseObject> comparator = new Comparator<ParseObject>() {
                            @Override
                            public int compare(ParseObject lhs, ParseObject rhs) {
                                ArrayList<String> lhLikeArray, lhDislikeArray, rhLikeArray, rhDislikeArray;
                                lhLikeArray = ((ArrayList<String>) lhs.get("likedBy") == null) ? (new ArrayList<String>()) : (ArrayList<String>) lhs.get("likedBy");
                                lhDislikeArray = ((ArrayList<String>) lhs.get("dislikedBy") == null) ? (new ArrayList<String>()) : (ArrayList<String>) lhs.get("dislikedBy");
                                rhLikeArray = ((ArrayList<String>) rhs.get("likedBy") == null) ? (new ArrayList<String>()) : (ArrayList<String>) rhs.get("likedBy");
                                rhDislikeArray = ((ArrayList<String>) rhs.get("dislikedBy") == null) ? (new ArrayList<String>()) : (ArrayList<String>) rhs.get("dislikedBy");

                                return (lhLikeArray.size() - lhDislikeArray.size()) - (rhLikeArray.size() - rhDislikeArray.size());
                            }
                        };

                        Comparator<ParseObject> reverseComparator = Collections.reverseOrder(comparator);

                        Collections.sort(wubbles, reverseComparator);


                        myWubbles = wubbles;
                        if (myWubbles != null && myWubbles.size() > 0) {


                            topCommentsAdapter = new TopCommentsAdapter(getActivity(), myWubbles, mFollowedUsers, movieId);
                            topCommentsRecyclerView.setAdapter(topCommentsAdapter);

                            //mTextView.setVisibility(View.GONE);
                            //mSpinner.setVisibility(View.GONE);
                            //feedRecyclerView.setVisibility(View.VISIBLE);
                        } else {
                            //mTextView.setVisibility(View.VISIBLE);
                            //mSpinner.setVisibility(View.GONE);
                        }


                    } else {
                        // handle problems here
                    }
                }
            });

        }


        return view;
    }


} public class MovieInformation implements Comparable<MovieInformation> {

    public boolean adult;
    public String backdrop_path;
    public int id;
    public String original_title;
    public String release_date;
    public String poster_path;
    public String overview;
    public List<Integer> genres;
    public int popularity;
    public String title;
    public boolean video;
    public float vote_average;
    public int vote_count;
    public String imdbId;


    public MovieInformation(JSONObject movieObject, int constructType) throws JSONException {

        adult = movieObject.getBoolean(TMDB_ADULT);
        backdrop_path = movieObject.getString(TMDB_BACKDROP_PATH);
        id = movieObject.getInt(TMDB_ID);
        original_title = movieObject.getString(TMDB_ORIGINAL_TITLE);
        release_date = movieObject.getString(TMDB_RELEASE_DATE);
        poster_path = movieObject.getString(TMDB_POSTER_PATH);
        popularity = movieObject.getInt(TMDB_POPULARITY);
        video = movieObject.getBoolean(TMDB_VIDEO);
        vote_average = movieObject.getInt(TMDB_VOTE_AVERAGE);
        vote_count = movieObject.getInt(TMDB_VOTE_COUNT);


        switch (constructType) {
            case 0: //BASIC
                overview = "";
                imdbId = "";
                genres = new ArrayList<Integer>();
                break;
            case 1: //EXTENDED

                imdbId = movieObject.getString(TMDB_IMDB_ID);

                overview = movieObject.getString(TMDB_OVERVIEW);

                JSONArray jsonArray = movieObject.getJSONArray(TMDB_GENRES);

                genres = new ArrayList<Integer>();
                for (int i = 0; i < jsonArray.length(); i++) {
                    genres.add(jsonArray.getJSONObject(i).getInt(TMDB_GENRE_ID));
                }
                break;
        }

        nullFix();
    }

    private void nullFix() {
        if (backdrop_path == null) {
            backdrop_path = "";
        }
        if (original_title == null) {
            original_title = "";
        }
        if (release_date == null) {
            release_date = "";
        }
        if (poster_path == null) {
            poster_path = "";
        }
        if (overview == null) {
            overview = "";
        }
    }


    public int compareTo(MovieInformation movieInformation) {
        float comparePopularity = movieInformation.popularity;
        float diff = comparePopularity - this.popularity;
        if (Math.abs(diff) > 1) {
            return (int) diff;
        } else if (diff < 0) {
            return -1;
        } else {
            return 1;
        }

    }
} public class VolleySingleton {

    private static VolleySingleton sInstance = null;

    private boolean isTransferComplete = true;

    private JSONObject mTMDBConfig;

    private RequestQueue mRequestQueue;

    private VolleySingleton() {
        mRequestQueue = Volley.newRequestQueue(AppGlobal.getAppContext());
        JsonObjectRequest configRequest = new JsonObjectRequest(Request.Method.GET, "http://api.themoviedb.org/3/configuration?api_key=" + TMDB_API_KEY, (JSONObject) null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        mTMDBConfig = response;
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(AppGlobal.getAppContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
        mRequestQueue.add(configRequest);
    }

    public static VolleySingleton getInstance() {
        if (sInstance == null) {
            sInstance = new VolleySingleton();
        }
        return sInstance;
    }


    public boolean getTransferState() {
        return isTransferComplete;
    }

    public void setTransferState(boolean newState) {
        isTransferComplete = newState;
    }

    public RequestQueue getRequestQueue() {
        return mRequestQueue;
    }
} public static final CustomSparseArray<String> GENRES; public static final int MOVIE_CONSTRUCTOR_EXTENDED = 1; public static final int MOVIE_TAB_BEST_COMMENTS = 1; public static final int MOVIE_TAB_FOLLOWING_COMMENTS = 0; public static final String OMDB_IMDB_RATING = "imdbRating"; public static final String OMDB_METASCORE = "Metascore"; public static final String ROTTEN_TOMATOES_CRITICS_SCORE = "critics_score"; public static final String ROTTEN_TOMATOES_RATINGS = "ratings";
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.parse.ParseUser;
import com.proxima.Wubble.R;
import com.proxima.Wubble.Tabs.SlidingTabLayout;
import com.proxima.Wubble.URLBuilder;
import com.proxima.Wubble.anim.AnimationUtils;
import com.proxima.Wubble.fragments.FollowingCommentsFragment;
import com.proxima.Wubble.fragments.TopCommentsFragment;
import com.proxima.Wubble.movie.MovieInformation;
import com.proxima.Wubble.network.VolleySingleton;
import com.squareup.picasso.Picasso;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.proxima.Wubble.Constants.GENRES;
import static com.proxima.Wubble.Constants.MOVIE_CONSTRUCTOR_EXTENDED;
import static com.proxima.Wubble.Constants.MOVIE_TAB_BEST_COMMENTS;
import static com.proxima.Wubble.Constants.MOVIE_TAB_FOLLOWING_COMMENTS;
import static com.proxima.Wubble.Constants.OMDB_IMDB_RATING;
import static com.proxima.Wubble.Constants.OMDB_METASCORE;
import static com.proxima.Wubble.Constants.ROTTEN_TOMATOES_CRITICS_SCORE;
import static com.proxima.Wubble.Constants.ROTTEN_TOMATOES_RATINGS;
package com.proxima.Wubble.activities;







public class MovieActivity extends ToolbarActivity {

    protected String LOG_TAG;

    private Context context;


    private ViewPager mPager;
    private SlidingTabLayout mTabs;

    private TextView movieDescriptionTextView;
    private TextView movieNameTextView;
    private ImageView movieImageImageView;
    private TextView movieReleaseDateTextView;
    private TextView movieGenresTextView;
    private TextView PopupDescTextView;

    private TextView imdbScoreTextView;
    private TextView rtScoreTextView;
    private TextView metascoreTextView;

    private PopupWindow pw;
    private RelativeLayout pwRelLay;

    private VolleySingleton volleySingleton;
    private RequestQueue requestQueue;

    private String movieName;
    private int movieId;
    private String movieComment;

    private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private boolean isTransferComplete = true;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie);
        activateToolbar();

        context = this;

        Bundle extras = getIntent().getExtras();

        LOG_TAG = getBaseContext().getClass().getSimpleName();

        movieDescriptionTextView = (TextView) findViewById(R.id.MoviePageMovieDescription);
        movieNameTextView = (TextView) findViewById(R.id.MoviePageMovieName);
        movieImageImageView = (ImageView) findViewById(R.id.MoviePageMovieImage);
        movieGenresTextView = (TextView) findViewById(R.id.MoviePageMovieGenres);
        movieReleaseDateTextView = (TextView) findViewById(R.id.MoviePageReleaseDate);
        imdbScoreTextView = (TextView) findViewById(R.id.MoviePageIMDBScore);
        metascoreTextView = (TextView) findViewById(R.id.MoviePageMetascore);
        rtScoreTextView = (TextView) findViewById(R.id.MoviePageRottenTomatoesScore);

        final ParseUser currentUser = ParseUser.getCurrentUser();
        final String currentUserName = currentUser.getUsername();

        volleySingleton = VolleySingleton.getInstance();
        requestQueue = volleySingleton.getRequestQueue();


        if (extras != null) {

            movieName = extras.getString("movieName");
            movieId = extras.getInt("movieId");

            movieNameTextView.setText(movieName);


            //String requestURL = TMDB_API_URL_BASE + TMDB_API_URL_MOVIE + Integer.toString(movieId) + TMDB_API_URL_API + TMDB_API_KEY;
            String requestURL = URLBuilder.getMovieWithIdURL(movieId);


            movieDescriptionTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    View PopupDesc = inflater.inflate(R.layout.description_popup, null, false);
                    pw = new PopupWindow(PopupDesc, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);

                    pw.showAtLocation(findViewById(R.id.MoviePageRelLay), Gravity.CENTER, 0, 0);
                    PopupDescTextView = (TextView) PopupDesc.findViewById(R.id.popup_desc);
                    PopupDescTextView.setText(movieDescriptionTextView.getText().toString());

                    pwRelLay = (RelativeLayout) PopupDesc.findViewById(R.id.descPopupRelLay);
                    AnimationUtils.PopupAnimate(pwRelLay, true);
                    pwRelLay.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            AnimationUtils.PopupAnimate(pwRelLay, false);
                            pw.dismiss();

                        }

                    });


                }
            });


            JsonObjectRequest movieRequest = new JsonObjectRequest(Request.Method.GET, requestURL, (JSONObject) null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            try {
                                MovieInformation currentMovie = new MovieInformation(response, MOVIE_CONSTRUCTOR_EXTENDED);
                                //String imageURL = TMDB_IMAGE_BASE_URL + TMDB_POSTER_SIZE_DEFAULT + response.getString(TMDB_POSTER_PATH);
                                if (!currentMovie.poster_path.isEmpty()) {
                                    String imageURL = URLBuilder.getImageURL(currentMovie.poster_path);
                                    Picasso.with(getBaseContext()).load(imageURL)
                                            .error(R.drawable.ic_action_user)
                                            .into(movieImageImageView);
                                }

                                movieDescriptionTextView.setText(currentMovie.overview);

                                if (!currentMovie.release_date.isEmpty()) {
                                    Date date = dateFormat.parse(currentMovie.release_date);
                                }


                                movieReleaseDateTextView.setText(currentMovie.release_date);

                                String genresText = "";
                                if (currentMovie.genres.size() > 0) {
                                    genresText += GENRES.get(currentMovie.genres.get(0));