public class ActivityMain extends BasicActivity implements IOverlayable, IToolbarHolder, ISlidingMenuHolder, ILoginManager,
        Toolbar.OnMenuItemClickListener {

    private static final int MIN_NUMBER_FRAGMENTS_IN_STACK = 1;
    private static final float MAX_OVERLAY_LEVEL = 0.8f;
    private static final int FRAGMENT_TRANSACTION_TIME = 300;
    private static final int WELLCOME_SCREEN_TIME = 2000;
    private static final long BACK_DOUBLE_CLICK_DELAY = 2000;

    private static final int RATE_MIN_INSTALL_DAYS = 1;
    private static final int RATE_MIN_INSTALL_TIMES = 7;

    public static boolean isFirstRun = true;

    /**
     * Type of last fragment shown by activity
     */
    public static int lastFragmentType = -1;

    /**
     * Number of last fragment shown by activity (for view pagers)
     */
    public static int lastChildFragmentNumber = -1;

    /**
     * Type of last fragment's child i.e Search (child of main featured fragment)
     */
    public static int lastChildFragmentType = -1;

    private Toolbar toolbar;
    private SlidingMenu slidingMenu;
    private View vOverlay;

    private CallbackManager callbackManager;

    private int[] notificationsActions = {NetworkTasksService.NOTIFICATIONS_SHOW_PODCASTS_SUBSCRIBED};
    private boolean doubleBackToExitPressedOnce;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setBackgroundDrawable(null);
        setContentView(R.layout.activity_main);

        //Toolbar
        toolbar = (Toolbar) findViewById(R.id.toolbar_main);

        int startedFrom = getIntent().getIntExtra(ActivityPlayer.ACTIVITY_STARTED_FROM, -1);

        if (isFirstRun && !Arrays.asList(notificationsActions).contains(startedFrom)) {
            toolbar.setVisibility(View.GONE);
            final FragmentWellcome fragmentWellcome = new FragmentWellcome();
            showFragment(R.id.fl_window, fragmentWellcome, FragmentWellcome.TAG);
            init();
            new Handler().postDelayed(new Runnable() {
                public void run() {
                    hideFragment(fragmentWellcome);
                    if (!Prefs.getBoolean(FragmentHelp.PREF_HELP_SHOWN, false)) { //!
                        showHelpFragment();
                    } else {
                        toolbar.setVisibility(View.VISIBLE);
                        showFragment(R.id.fl_content, getStartFragment(), FragmentMediaItemsGrid.TAG);
                    }
                }
            }, WELLCOME_SCREEN_TIME);
        } else {
            init();
            toolbar.setVisibility(View.VISIBLE);

            int startedFragmentNumber = ActivityMain.lastChildFragmentNumber;

            if (startedFrom == NetworkTasksService.NOTIFICATIONS_SHOW_PODCASTS_SUBSCRIBED) {
                startedFragmentNumber = 1;
                startedFrom = MediaItemType.PODCAST.ordinal();
                NotificationManager nMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                nMgr.cancel(NetworkTasksService.NEW_EPISODS_NOTIFICATION_ID);
            }

            FragmentMediaItemsGrid fragmentMediaItemsGrid = new FragmentMediaItemsGrid();
            fragmentMediaItemsGrid.setMediaItemType(startedFrom == MediaItemType.PODCAST.ordinal() ? MediaItemType.PODCAST : MediaItemType.RADIO);
            if (startedFragmentNumber >= 0) {
                fragmentMediaItemsGrid.setStartItemNumber(startedFragmentNumber);
            }
            showFragment(R.id.fl_content, fragmentMediaItemsGrid, FragmentMediaItemsGrid.TAG);
            AppRate.with(this)
                    .setInstallDays(RATE_MIN_INSTALL_DAYS)
                    .setLaunchTimes(RATE_MIN_INSTALL_TIMES)
                    .setShowLaterButton(true) // default true
                    .monitor();

            // Show a dialog if meets conditions
            AppRate.showRateDialogIfMeetsConditions(this);
        }
        isFirstRun = false;
    }

    private void init() {
        UpodsApplication.initAllResources();
        vOverlay = findViewById(R.id.vOverlay);

        //Toolbar
        toolbar.inflateMenu(R.menu.menu_activity_main);
        toolbar.setOnMenuItemClickListener(this);
        toolbar.setTitleTextColor(getResources().getColor(R.color.white));

        //Social
        callbackManager = CallbackManager.Factory.create();

        MenuItem searchMenuItem = toolbar.getMenu().findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchMenuItem.getActionView();
        UIHelper.setSearchViewStyle(searchView);
        UIHelper.changeSearchViewTextColor(searchView, Color.WHITE);

        slidingMenu = new SlidingMenu(this, toolbar);
    }

    private void showHelpFragment() {
        FragmentHelp fragmentHelp = new FragmentHelp();
        fragmentHelp.setCloseClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                toolbar.setVisibility(View.VISIBLE);
                FragmentMediaItemsGrid fragmentMediaItemsGrid = new FragmentMediaItemsGrid();
                fragmentMediaItemsGrid.setMediaItemType(MediaItemType.RADIO);
                showFragment(R.id.fl_content, fragmentMediaItemsGrid, FragmentMediaItemsGrid.TAG);
            }
        });
        showFragment(R.id.fl_content, fragmentHelp, FragmentHelp.TAG);
    }

    private FragmentMediaItemsGrid getStartFragment() {
        FragmentMediaItemsGrid fragmentMediaItemsGrid = new FragmentMediaItemsGrid();
        String startScreen = SettingsManager.getInstace().getStringSettingValue(SettingsManager.JS_START_SCREEN);
        if (startScreen.equals("rs_subscribed")) {
            fragmentMediaItemsGrid.setMediaItemType(MediaItemType.RADIO);
            fragmentMediaItemsGrid.setStartItemNumber(1);
        } else if (startScreen.equals("rs_recent")) {
            fragmentMediaItemsGrid.setMediaItemType(MediaItemType.RADIO);
            fragmentMediaItemsGrid.setStartItemNumber(2);
        } else if (startScreen.equals("podcasts_featured")) {
            fragmentMediaItemsGrid.setMediaItemType(MediaItemType.PODCAST);
            fragmentMediaItemsGrid.setStartItemNumber(0);
        } else if (startScreen.equals("podcasts_favorites")) {
            fragmentMediaItemsGrid.setMediaItemType(MediaItemType.PODCAST);
            fragmentMediaItemsGrid.setStartItemNumber(1);
        } else if (startScreen.equals("podcasts_downloaded")) {
            fragmentMediaItemsGrid.setMediaItemType(MediaItemType.PODCAST);
            fragmentMediaItemsGrid.setStartItemNumber(2);
        } else {
            fragmentMediaItemsGrid.setMediaItemType(MediaItemType.RADIO);
            fragmentMediaItemsGrid.setStartItemNumber(0);
        }
        return fragmentMediaItemsGrid;
    }

    @Override
    public void onBackPressed() {
        if (getFragmentManager().findFragmentByTag(getLatestFragmentTag()) instanceof ICustumziedBackPress) {
            boolean performBackPress = ((ICustumziedBackPress) getFragmentManager().findFragmentByTag(getLatestFragmentTag())).onBackPressed();
            if (!performBackPress) {
                return;
            }
        }

        if (getFragmentManager().getBackStackEntryCount() > MIN_NUMBER_FRAGMENTS_IN_STACK) {
            if (getLatestFragmentTag().equals(FragmentSearch.TAG)) {
                toolbar.getMenu().findItem(R.id.action_search).collapseActionView();
                getFragmentManager().popBackStack();
            } else {
                if (isOverlayShown()) {
                    toggleOverlay();
                }
                getFragmentManager().popBackStack();
            }
        } else {
            if (doubleBackToExitPressedOnce) {
                finish();
                return;
            }

            this.doubleBackToExitPressedOnce = true;
            Toast.makeText(this, R.string.clcik_back_exit, Toast.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    doubleBackToExitPressedOnce = false;
                }
            }, BACK_DOUBLE_CLICK_DELAY);
        }

    }

    @Override
    public void toggleOverlay() {
        ObjectAnimator alphaAnimation;
        if (isOverlayShown()) {
            alphaAnimation = ObjectAnimator.ofFloat(vOverlay, View.ALPHA, MAX_OVERLAY_LEVEL, 0);
        } else {
            alphaAnimation = ObjectAnimator.ofFloat(vOverlay, View.ALPHA, 0, MAX_OVERLAY_LEVEL);
        }
        alphaAnimation.setDuration(FRAGMENT_TRANSACTION_TIME);
        alphaAnimation.start();
    }

    @Override
    public boolean isOverlayShown() {
        return vOverlay.getAlpha() != 0;
    }

    @Override
    public void setOverlayAlpha(int alphaPercent) {
        vOverlay.getBackground().setAlpha(alphaPercent);
    }

    @Override
    public Toolbar getToolbar() {
        return toolbar;
    }

    @Override
    public SlidingMenu getSlidingMenu() {
        return slidingMenu;
    }

    @Override
    public void setSlidingMenuHeader(String itemName) {
        slidingMenu.getAdapter().setSelectedRow(itemName);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //Facebook analytics
        //AppEventsLogger.activateApp(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //Facebook analytics
        //AppEventsLogger.deactivateApp(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (currentContextMenuData != null && currentContextMenuData instanceof MediaItem) {
            Toast.makeText(this, ((MediaItem) currentContextMenuData).getName(), Toast.LENGTH_SHORT).show();
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        if (contextMenuType == ContextMenuType.PODCAST_MIDDLE_SCREEN) {
            inflater.inflate(R.menu.menu_basic_sceleton, menu);
            menu.add(getString(R.string.about_podcast));
            if (((Podcast) currentContextMenuData).isDownloaded) {
                menu.add(getString(R.string.open_on_disk));
                menu.add(getString(R.string.remove_all_episods));
            }
        } else if (contextMenuType == ContextMenuType.EPISODE_MIDDLE_SCREEN) {
            inflater.inflate(R.menu.menu_basic_sceleton, menu);
            menu.add(getString(R.string.marks_as_played));
            Track track = ((MediaItem.MediaItemBucket) currentContextMenuData).track;
            if (((Episode) track).isDownloaded) {
                menu.add(getString(R.string.delete));
            }
        } else if (contextMenuType == ContextMenuType.PROFILE) {
            inflater.inflate(R.menu.menu_logedin_profile, menu);
        } else {
            inflater.inflate(R.menu.menu_activity_main, menu);
        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (currentContextMenuData != null && currentContextMenuData instanceof Podcast
                && item.getTitle().equals(getString(R.string.about_podcast))) {
            YandexMetrica.reportEvent(Analytics.MIDDLE_SCREEN_ABOUT_PODCAST);
            ContextMenuHelper.showAboutPodcastDialog((Podcast) currentContextMenuData, this);
        } else if (currentContextMenuData != null && currentContextMenuData instanceof Podcast
                && item.getTitle().equals(getString(R.string.open_on_disk))) {
            YandexMetrica.reportEvent(Analytics.MIDDLE_SCREEN_OPEN_ON_DISK);
            ContextMenuHelper.showPodcastInFolder((MediaItem) currentContextMenuData, this);
        } else if (currentContextMenuData != null && currentContextMenuData instanceof Podcast
                && item.getTitle().equals(getString(R.string.remove_all_episods))) {
            YandexMetrica.reportEvent(Analytics.MIDDLE_REMOVE_ALL_EPISODES);
            ContextMenuHelper.removeAllDonwloadedEpisods(this, (Podcast) currentContextMenuData, onContextItemSelected);
        } else if (currentContextMenuData != null && currentContextMenuData instanceof MediaItem.MediaItemBucket
                && item.getTitle().equals(getString(R.string.delete))) {
            YandexMetrica.reportEvent(Analytics.MIDDLE_REMOVE_EPISODE);
            MediaItem mediaItem = ((MediaItem.MediaItemBucket) currentContextMenuData).mediaItem;
            Track track = ((MediaItem.MediaItemBucket) currentContextMenuData).track;
            ContextMenuHelper.removeDonwloadedTrack(this, track, mediaItem, onContextItemSelected);
        } else if (id == R.id.itemLogout) {
            LoginMaster.getInstance().logout();
            getSlidingMenu().updateHeader(true);
            if (onContextItemSelected != null) {
                onContextItemSelected.operationFinished();
            }
        }
        return super.onContextItemSelected(item);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
        if (getFragmentManager().findFragmentByTag(getLatestFragmentTag()) instanceof FragmentProfile) {
            FragmentProfile fragmentProfile = (FragmentProfile) getFragmentManager().findFragmentByTag(getLatestFragmentTag());
            fragmentProfile.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public CallbackManager getFacebookCallbackManager() {
        return callbackManager;
    }


    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.add_podcast) {
            ContextMenuHelper.showAddMediaDialog(this, MediaItemType.PODCAST);
        } else if (id == R.id.add_radio) {
            ContextMenuHelper.showAddMediaDialog(this, MediaItemType.RADIO);
        }
        return true;
    }

} public class MediaPagesAdapter extends FragmentStatePagerAdapter {

    private final int PODCASTS_PAGES_COUNT = 4;
    private final int RADIO_PAGES_COUNT = 3;
    private MediaItemType mediaItemType;
    private int pagesCount;

    private Hashtable<Integer, WeakReference<Fragment>> fragmentReferences;


    public MediaPagesAdapter(FragmentManager fm, MediaItemType mediaItemType) {
        super(fm);
        this.fragmentReferences = new Hashtable<>();
        this.mediaItemType = mediaItemType;
        if (mediaItemType == MediaItemType.RADIO) {
            this.pagesCount = RADIO_PAGES_COUNT;
        } else {
            this.pagesCount = PODCASTS_PAGES_COUNT;
        }

    }


    @Override
    public Fragment getItem(int position) {
        Fragment currentFragment = null;
        if (mediaItemType == MediaItemType.RADIO) {
            currentFragment = getRadioFragment(position);
        } else {
            currentFragment = getPodcastFragment(position);
        }
        return currentFragment;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
        fragmentReferences.put(position, new WeakReference<Fragment>(createdFragment));
        return createdFragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        String title = "";
        if (mediaItemType == MediaItemType.RADIO) {
            title = getRadioPageTitle(position);
        } else {
            title = getPodcastTitle(position);
        }

        return title;
    }

    private String getPodcastTitle(int position) {
        switch (position) {
            case 0:
                return UpodsApplication.getContext().getString(R.string.page_featured);
            case 1:
                return UpodsApplication.getContext().getString(R.string.page_favorites);
            case 2:
                return UpodsApplication.getContext().getString(R.string.page_downloaded);
            case 3:
                return UpodsApplication.getContext().getString(R.string.page_categories);
        }
        return "";
    }

    private Fragment getPodcastFragment(int position) {
        Fragment podcastFragment = null;
        switch (position) {
            case 0:
                podcastFragment = new FragmentPodcastFeatured();
                break;
            case 1:
                podcastFragment = new FragmentMediaItemsList();
                ((FragmentMediaItemsList) podcastFragment).setMediaItemType(MediaItemType.PODCAST_FAVORITE);
                break;
            case 2:
                podcastFragment = new FragmentMediaItemsList();
                ((FragmentMediaItemsList) podcastFragment).setMediaItemType(MediaItemType.PODCAST_DOWNLOADED);
                break;
            case 3:
                podcastFragment = new FragmentMediaItemsCategories();
                break;
        }
        return podcastFragment;
    }

    private Fragment getRadioFragment(int position) {
        Fragment radioFragment = null;
        switch (position) {
            case 0:
                radioFragment = new FragmentMainFeatured();
                break;
            case 1:
                radioFragment = new FragmentMediaItemsList();
                ((FragmentMediaItemsList) radioFragment).setMediaItemType(MediaItemType.RADIO_SUBSCRIBED);
                break;
            case 2:
                radioFragment = new FragmentMediaItemsList();
                ((FragmentMediaItemsList) radioFragment).setMediaItemType(MediaItemType.RADIO_RECENT);
                break;
        }
        return radioFragment;
    }

    private String getRadioPageTitle(int position) {
        switch (position) {
            case 0:
                return UpodsApplication.getContext().getString(R.string.page_featured);
            case 1:
                return UpodsApplication.getContext().getString(R.string.page_subscribed);
            case 2:
                return UpodsApplication.getContext().getString(R.string.page_recent);
        }
        return "";
    }

    @Override
    public int getCount() {
        return pagesCount;
    }

    public void notifyChangesInFragments(ProfileManager.ProfileUpdateEvent profileUpdateEvent) {
        for (int i = 0; i < getCount(); i++) {
            WeakReference<Fragment> ref = fragmentReferences.get(i);
            if (ref != null) {
                Fragment fragment = ref.get();
                if (fragment instanceof FragmentMediaItemsList) {
                    ((FragmentMediaItemsList) fragment).notifyMediaItemChanges(profileUpdateEvent);
                } else if (fragment instanceof FragmentPodcastFeatured) {
                    ((FragmentPodcastFeatured) fragment).notifyMediaItemChanges(profileUpdateEvent);
                } else if (fragment instanceof FragmentMainFeatured) {
                    ((FragmentMainFeatured) fragment).notifyMediaItemChanges(profileUpdateEvent);
                }
            }
        }
        notifyDataSetChanged();
    }

    public void reloadAllFragmentsData() {
        for (int i = 0; i < getCount(); i++) {
            WeakReference<Fragment> ref = fragmentReferences.get(i);
            Fragment fragment = ref.get();
            if (fragment != null && fragment instanceof FragmentMediaItemsList) {
                ((FragmentMediaItemsList) fragment).reloadAllData();
            }
        }
    }
} public class ProfileManager {

    public static final String JS_SUBSCRIBED_PODCASTS = "subscribedPodcasts";
    public static final String JS_SUBSCRIBED_STATIONS = "subscribedStations";
    public static final String JS_RECENT_STATIONS = "recentStations";

    public static ProfileManager profileManager;
    private IOperationFinishWithDataCallback profileSavedCallback;


    public static class ProfileUpdateEvent {
        public String updateListType;
        public MediaItem mediaItem;
        public boolean isRemoved;

        public ProfileUpdateEvent(String updateListType, MediaItem mediaItem, boolean isRemoved) {
            this.updateListType = updateListType;
            this.mediaItem = mediaItem;
            this.isRemoved = isRemoved;
        }
    }

    private ProfileManager() {

    }

    public synchronized static ProfileManager getInstance() {
        if (profileManager == null) {
            profileManager = new ProfileManager();
        }
        return profileManager;
    }

    public void setProfileSavedCallback(IOperationFinishWithDataCallback profileSavedCallback) {
        this.profileSavedCallback = profileSavedCallback;
    }

    private ArrayList<Long> getMediaListIds(String mediaType, String listType) {
        SQLiteDatabase database = UpodsApplication.getDatabaseManager().getReadableDatabase();
        String[] args1 = {mediaType, listType};
        ArrayList<Long> ids = new ArrayList<>();
        String table = mediaType.equals(MediaListItem.TYPE_RADIO) ? "radio_stations" : "podcasts";
        Cursor cursor = database.rawQuery("SELECT p.id FROM " + table + " as p\n" +
                "LEFT JOIN media_list as ml\n" +
                "ON p.id = ml.media_id\n" +
                "WHERE ml.media_type = ? and ml.list_type = ?", args1);
        while (cursor.moveToNext()) {
            ids.add(cursor.getLong(cursor.getColumnIndex("id")));
        }
        cursor.close();
        return ids;
    }

    private ArrayList<Podcast> getPodcastsForMediaType(String mediaType) {
        SQLiteDatabase database = UpodsApplication.getDatabaseManager().getReadableDatabase();
        ArrayList<Long> ids = getMediaListIds(MediaListItem.TYPE_PODCAST,
                mediaType.equals(MediaListItem.DOWNLOADED) ? MediaListItem.SUBSCRIBED : MediaListItem.DOWNLOADED);
        ArrayList<Podcast> podcasts = new ArrayList<>();
        String[] args2 = {MediaListItem.TYPE_PODCAST, mediaType};
        Cursor cursor = database.rawQuery("SELECT p.* FROM podcasts as p\n" +
                "LEFT JOIN media_list as ml\n" +
                "ON p.id = ml.media_id\n" +
                "WHERE ml.media_type = ? and ml.list_type = ? " +
                "ORDER BY id DESC", args2);
        while (cursor.moveToNext()) {
            Podcast podcast = Podcast.withCursor(cursor);
            if (mediaType.equals(MediaListItem.DOWNLOADED)) {
                podcast.isDownloaded = true;
                if (ids.contains(podcast.id)) {
                    podcast.isSubscribed = true;
                }
            } else if (mediaType.equals(MediaListItem.SUBSCRIBED)) {
                podcast.isSubscribed = true;
                if (ids.contains(podcast.id)) {
                    podcast.isDownloaded = true;
                }
            }
            podcasts.add(podcast);
        }
        cursor.close();

        Podcast.syncWithDb(podcasts);

        return podcasts;
    }

    private ArrayList<RadioItem> getRadioStationsForMediaType(String mediaType) {
        SQLiteDatabase database = UpodsApplication.getDatabaseManager().getReadableDatabase();
        ArrayList<Long> ids = getMediaListIds(MediaListItem.TYPE_RADIO,
                mediaType.equals(MediaListItem.RECENT) ? MediaListItem.SUBSCRIBED : MediaListItem.RECENT);
        ArrayList<RadioItem> radioItems = new ArrayList<>();
        String[] args2 = {MediaListItem.TYPE_RADIO, mediaType};

        Cursor cursor = database.rawQuery("SELECT r.* FROM radio_stations as r\n" +
                "LEFT JOIN media_list as ml\n" +
                "ON r.id = ml.media_id\n" +
                "WHERE ml.media_type = ? and ml.list_type = ? " +
                "ORDER BY id DESC", args2);

        while (cursor.moveToNext()) {
            RadioItem radioItem = RadioItem.withCursor(cursor);
            if (mediaType.equals(MediaListItem.RECENT)) {
                radioItem.isRecent = true;
                if (ids.contains(radioItem.id)) {
                    radioItem.isSubscribed = true;
                }
            } else if (mediaType.equals(MediaListItem.SUBSCRIBED)) {
                radioItem.isSubscribed = true;
                if (ids.contains(radioItem.id)) {
                    radioItem.isRecent = true;
                }
            }
            radioItems.add(radioItem);
        }
        cursor.close();
        return radioItems;
    }

    private void addTrack(MediaItem mediaItem, Track track, String listType) {
        if (mediaItem instanceof Podcast && track instanceof Episode) {
            SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
            boolean isNotifyChanges = false;
            Podcast podcast = (Podcast) mediaItem;
            Episode episode = (Episode) track;

            //1. Save episode/podcast if needed
            if (!podcast.isExistsInDb) {
                podcast.save();
            }
            if (!episode.isExistsInDb) {
                episode.save(podcast.id);
            }

            //2. Add podcast to media_list if needed
            if ((!podcast.isDownloaded && listType.equals(MediaListItem.DOWNLOADED)) ||
                    (!podcast.hasNewEpisodes && listType.equals(MediaListItem.NEW))) {
                ContentValues values = new ContentValues();
                values.put("media_id", mediaItem.id);
                values.put("media_type", MediaListItem.TYPE_PODCAST);
                values.put("list_type", listType);
                database.insert("media_list", null, values);
                isNotifyChanges = true;
            }

            //3. Create podcasts_episodes_rel
            if ((!episode.isDownloaded && listType.equals(MediaListItem.DOWNLOADED)) ||
                    (!episode.isNew && listType.equals(MediaListItem.NEW))) {
                ContentValues values = new ContentValues();
                values.put("podcast_id", podcast.id);
                values.put("episode_id", episode.id);
                values.put("type", listType);
                database.insert("podcasts_episodes_rel", null, values);
            }

            //4. Update objects
            if (listType.equals(MediaListItem.DOWNLOADED)) {
                podcast.isDownloaded = true;
                episode.isDownloaded = true;
                if (isNotifyChanges) {
                    notifyChanges(new ProfileUpdateEvent(MediaListItem.DOWNLOADED, mediaItem, false));
                }
            } else if (listType.equals(MediaListItem.NEW)) {
                podcast.hasNewEpisodes = true;
                episode.isNew = true;
                if (!Podcast.hasEpisodeWithTitle(podcast, episode)) {
                    podcast.getEpisodes().add(episode);
                }
                if (Looper.myLooper() == Looper.getMainLooper()) {
                    notifyChanges(new ProfileUpdateEvent(MediaListItem.NEW, mediaItem, false));
                }
            }
        }
    }

    private void removeTrack(MediaItem mediaItem, Track track, String listType) {
        if (mediaItem instanceof Podcast && track instanceof Episode) {
            SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
            Podcast podcast = (Podcast) mediaItem;
            Episode episode = (Episode) track;

            //Remove reletionships -> then remove episode
            String args[] = {String.valueOf(podcast.id), String.valueOf(episode.id), listType};
            database.delete("podcasts_episodes_rel", "podcast_id = ? AND episode_id = ? AND type = ?", args);

            if (listType.equals(MediaListItem.DOWNLOADED)) {
                File episodeFile = new File(episode.getAudeoUrl());
                episodeFile.delete();
                episode.isDownloaded = false;
                if (!episode.isNew) {
                    episode.remove();
                }
            } else if (listType.equals(MediaListItem.NEW)) {
                episode.isNew = false;
                if (!episode.isDownloaded) {
                    episode.remove();
                }
            }

            if (listType.equals(MediaListItem.DOWNLOADED) && podcast.getDownloadedEpisodsCount() == 0) {
                String args2[] = {String.valueOf(podcast.id), MediaListItem.TYPE_PODCAST, MediaListItem.DOWNLOADED};
                database.delete("media_list", "media_id = ? AND media_type = ? AND list_type = ?", args2);
                podcast.isDownloaded = false;
                notifyChanges(new ProfileUpdateEvent(MediaListItem.DOWNLOADED, mediaItem, true));
            } else if (listType.equals(MediaListItem.NEW) && podcast.getNewEpisodsCount() == 0) {
                podcast.hasNewEpisodes = false;
                String args2[] = {String.valueOf(podcast.id), MediaListItem.TYPE_PODCAST, MediaListItem.NEW};
                database.delete("media_list", "media_id = ? AND media_type = ? AND list_type = ?", args2);
            }

            if (listType.equals(MediaListItem.NEW) && Looper.myLooper() == Looper.getMainLooper()) {
                //If we are in main thread and were changes in count of new episodes -> notify provider
                notifyChanges(new ProfileUpdateEvent(MediaListItem.NEW, mediaItem, false));
            }

        }
    }

    public ArrayList<Podcast> getDownloadedPodcasts() {
        return getPodcastsForMediaType(MediaListItem.DOWNLOADED);
    }

    public ArrayList<Podcast> getSubscribedPodcasts() {
        return getPodcastsForMediaType(MediaListItem.SUBSCRIBED);
    }

    public ArrayList<RadioItem> getSubscribedRadioItems() {
        return getRadioStationsForMediaType(MediaListItem.SUBSCRIBED);
    }

    public ArrayList<RadioItem> getRecentRadioItems() {
        return getRadioStationsForMediaType(MediaListItem.RECENT);
    }

    public int getTrackPosition(Track track) {
        int trackPostion = -1;
        SQLiteDatabase database = UpodsApplication.getDatabaseManager().getReadableDatabase();
        String args[] = {track.getTitle()};
        Cursor cursor = database.rawQuery("SELECT position FROM tracks_positions WHERE track_name = ?", args);
        if (cursor.getCount() > 0) {
            cursor.moveToFirst();
            trackPostion = cursor.getInt(cursor.getColumnIndex("position"));
        }
        return trackPostion;
    }

    public void addSubscribedMediaItem(MediaItem mediaItem) {
        if (!mediaItem.isSubscribed) {
            String mediaType = MediaListItem.TYPE_RADIO;
            if (mediaItem instanceof Podcast) {
                mediaType = MediaListItem.TYPE_PODCAST;
                Podcast podcast = ((Podcast) mediaItem);
                if (!mediaItem.isExistsInDb) {
                    podcast.save();
                }
                Feed.removeFeed(podcast.getFeedUrl());
                Feed.saveAsFeed(podcast.getFeedUrl(), podcast.getEpisodes(), true);
            } else if (mediaItem instanceof RadioItem) {
                if (!mediaItem.isExistsInDb) {
                    ((RadioItem) mediaItem).save();
                }
            }
            ContentValues values = new ContentValues();
            values.put("media_id", mediaItem.id);
            values.put("media_type", mediaType);
            values.put("list_type", MediaListItem.SUBSCRIBED);
            UpodsApplication.getDatabaseManager().getWritableDatabase().insert("media_list", null, values);
            mediaItem.isSubscribed = true;

            if (mediaItem instanceof Podcast && getSubscribedPodcasts().size() == 1) {
                UpodsApplication.setAlarmManagerTasks();
            }
        }
        notifyChanges(new ProfileUpdateEvent(MediaListItem.SUBSCRIBED, mediaItem, false));
    }

    public void addRecentMediaItem(MediaItem mediaItem) {
        if (mediaItem instanceof RadioItem) {
            if (!((RadioItem) mediaItem).isRecent) {
                if (!mediaItem.isExistsInDb) {
                    ((RadioItem) mediaItem).save();
                }
                ContentValues values = new ContentValues();
                values.put("media_id", mediaItem.id);
                values.put("media_type", MediaListItem.TYPE_RADIO);
                values.put("list_type", MediaListItem.RECENT);
                UpodsApplication.getDatabaseManager().getWritableDatabase().insert("media_list", null, values);
                ((RadioItem) mediaItem).isRecent = true;
                notifyChanges(new ProfileUpdateEvent(MediaListItem.RECENT, mediaItem, false));
            }
        }
    }

    public void addNewTrack(MediaItem mediaItem, Track track) {
        addTrack(mediaItem, track, MediaListItem.NEW);
    }

    public void addDownloadedTrack(MediaItem mediaItem, Track track) {
        addTrack(mediaItem, track, MediaListItem.DOWNLOADED);
    }

    public void saveTrackPosition(Track track, int position) {
        SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("track_name", track.getTitle());
        values.put("position", position);
        database.replace("tracks_positions", null, values);
    }

    public void removeNewTrack(MediaItem mediaItem, Track track) {
        removeTrack(mediaItem, track, MediaListItem.NEW);
    }

    public void removeDownloadedTrack(MediaItem mediaItem, Track track) {
        removeTrack(mediaItem, track, MediaListItem.DOWNLOADED);
    }

    public void removeRecentMediaItem(MediaItem mediaItem) {
        if (mediaItem instanceof RadioItem) {
            SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
            String args[] = {String.valueOf(mediaItem.id), MediaListItem.TYPE_RADIO, MediaListItem.RECENT};
            database.delete("media_list", "media_id = ? AND media_type = ? AND list_type = ?", args);
            ((RadioItem) mediaItem).isRecent = false;

            //Remove media item from DB if it doesn't use
            if (!((RadioItem) mediaItem).isSubscribed) {
                String args2[] = {String.valueOf(mediaItem.id)};
                database.delete("radio_stations", "id = ?", args2);
            }
        }
        notifyChanges(new ProfileUpdateEvent(MediaListItem.SUBSCRIBED, mediaItem, true));
    }

    public void removeSubscribedMediaItem(MediaItem mediaItem) {
        SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
        String type = MediaListItem.TYPE_RADIO;
        if (mediaItem instanceof Podcast) {
            type = MediaListItem.TYPE_PODCAST;
        }
        mediaItem.isSubscribed = false;
        String args[] = {String.valueOf(mediaItem.id), type, MediaListItem.SUBSCRIBED};
        database.delete("media_list", "media_id = ? AND media_type = ? AND list_type = ?", args);

        //Remove media item from DB if it doesn't use
        if (mediaItem instanceof RadioItem && !((RadioItem) mediaItem).isRecent) {
            String args2[] = {String.valueOf(mediaItem.id)};
            database.delete("radio_stations", "id = ?", args2);
        } else if (mediaItem instanceof Podcast && !((Podcast) mediaItem).isDownloaded && !((Podcast) mediaItem).hasNewEpisodes) {
            String args2[] = {String.valueOf(mediaItem.id)};
            database.delete("podcasts", "id = ?", args2);
        }

        notifyChanges(new ProfileUpdateEvent(MediaListItem.SUBSCRIBED, mediaItem, true));
    }

    public void notifyChanges(ProfileUpdateEvent updateEvent) {
        if (profileSavedCallback != null) {
            profileSavedCallback.operationFinished(updateEvent);
        }
    }

    private void initSubscribedPodcasts(JSONArray jSubscribedPodcasts) {
        try {
            SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
            ArrayList<Podcast> subscribedPodcasts = new ArrayList<>();
            for (int i = 0; i < jSubscribedPodcasts.length(); i++) {
                Podcast podcast = new Podcast(jSubscribedPodcasts.getJSONObject(i));
                subscribedPodcasts.add(podcast);
            }

            if (subscribedPodcasts.isEmpty()) {
                return;
            }

            Podcast.syncWithDb(subscribedPodcasts);
            for (Podcast podcast : subscribedPodcasts) {
                if (!podcast.isSubscribed) {
                    addSubscribedMediaItem(podcast);
                }
            }
            ArrayList<String> ids = MediaItem.getIds(subscribedPodcasts);
            if (ids.size() == 0) {
                return;
            }
            ArrayList<String> args = new ArrayList<>();
            args.add(MediaListItem.TYPE_PODCAST);
            args.add(MediaListItem.SUBSCRIBED);
            args.addAll(ids);
            database.delete("media_list", "media_type = ? AND list_type = ? AND media_id not in (" + SQLdatabaseManager.makePlaceholders(ids.size()) + ")",
                    args.toArray(new String[args.size()]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initRadioStations(JSONArray jStations, String listType) {
        try {
            SQLiteDatabase database = UpodsApplication.getDatabaseManager().getWritableDatabase();
            ArrayList<RadioItem> radioStations = new ArrayList<>();
            for (int i = 0; i < jStations.length(); i++) {
                RadioItem radioItem = new RadioItem(jStations.getJSONObject(i));
                radioStations.add(radioItem);
            }

            if (radioStations.isEmpty()) {
                return;
            }

            RadioItem.syncWithDb(radioStations);
            for (RadioItem radioItem : radioStations) {
                if (!radioItem.isSubscribed && listType.equals(MediaListItem.SUBSCRIBED)) {
                    addSubscribedMediaItem(radioItem);
                } else if (!radioItem.isRecent && listType.equals(MediaListItem.RECENT)) {
                    addRecentMediaItem(radioItem);
                }
            }
            ArrayList<String> ids = MediaItem.getIds(radioStations);

            if (ids.size() == 0) {
                return;
            }

            ArrayList<String> args = new ArrayList<>();
            args.add(MediaListItem.TYPE_RADIO);
            args.add(listType);
            args.addAll(ids);
            database.delete("media_list", "media_type = ? AND list_type = ? AND media_id not in (" + SQLdatabaseManager.makePlaceholders(ids.size()) + ")",
                    args.toArray(new String[args.size()]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void readFromJson(JSONObject rootProfile) {
        try {
            //Read from JSON -> syncWithDB -> save all which not exists -> remove all which not in JSON
            // -> UI will be notified inside init... functions

            initSubscribedPodcasts(rootProfile.getJSONArray(JS_SUBSCRIBED_PODCASTS));
            initRadioStations(rootProfile.getJSONArray(JS_SUBSCRIBED_STATIONS), MediaListItem.SUBSCRIBED);
            initRadioStations(rootProfile.getJSONArray(JS_RECENT_STATIONS), MediaListItem.RECENT);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    public JSONObject getAsJson() {
        JSONObject rootProfile = new JSONObject();
        try {
            rootProfile.put(JS_RECENT_STATIONS, RadioItem.toJsonArray(getRecentRadioItems()));
            rootProfile.put(JS_SUBSCRIBED_STATIONS, RadioItem.toJsonArray(getSubscribedRadioItems()));
            rootProfile.put(JS_SUBSCRIBED_PODCASTS, Podcast.toJsonArray(getSubscribedPodcasts()));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return rootProfile;
    }

} public class SmallPlayer implements IPlayerStateListener, View.OnClickListener {

    private static final int COVER_IMAGE_SIZE = UIHelper.dpToPixels(64);

    private ImageView imgCover;
    private TextView tvTitle;
    private TextView tvSubTtitle;
    private SeekBar sbSmallPlayer;
    private ImageButton btnPlay;
    private RelativeLayout rlSmallPLayer;
    private Activity mActivity;
    private UniversalPlayer universalPlayer;

    private PlayerPositionUpdater playerPositionUpdater;

    private long maxDuration = -1;

    private View.OnClickListener btnPlayOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            UniversalPlayer universalPlayer = UniversalPlayer.getInstance();
            universalPlayer.toggle();
            btnPlay.setImageResource(universalPlayer.isPlaying() ? R.drawable.ic_pause_white : R.drawable.ic_play_white);
        }
    };

    public SmallPlayer(View parentView, Activity mActivity) {
        this.mActivity = mActivity;
        this.universalPlayer = UniversalPlayer.getInstance();
        this.rlSmallPLayer = (RelativeLayout) parentView.findViewById(R.id.rlSmallPlayer);
        if (this.rlSmallPLayer != null) {
            this.imgCover = (ImageView) parentView.findViewById(R.id.imgSmallPlayerCover);
            this.tvTitle = (TextView) parentView.findViewById(R.id.tvSmallPlayerTitle);
            this.tvSubTtitle = (TextView) parentView.findViewById(R.id.tvSmallPlayerSubTtile);
            this.btnPlay = (ImageButton) parentView.findViewById(R.id.btnSmallPlayerPlay);
            this.btnPlay.setOnClickListener(btnPlayOnClickListener);
            this.sbSmallPlayer = (SeekBar) parentView.findViewById(R.id.sbSmallPlayer);
        }
    }

    private void initPlayerUI() {
        if (this.rlSmallPLayer == null) {
            return;
        }
        rlSmallPLayer.setOnClickListener(this);
        if (universalPlayer.isPrepaired) {
            this.rlSmallPLayer.setVisibility(View.VISIBLE);
            this.btnPlay.setImageResource(universalPlayer.isPlaying() ? R.drawable.ic_pause_white : R.drawable.ic_play_white);
            MediaItem playingMediaItem = universalPlayer.getPlayingMediaItem();
            if (playingMediaItem instanceof Podcast) {
                tvTitle.setText(((Podcast) playingMediaItem).getSelectedTrack().getTitle());
            } else {
                tvTitle.setText(playingMediaItem.getName());
            }
            this.tvSubTtitle.setText(playingMediaItem.getSubHeader());
            if (playingMediaItem.getCoverImageUrl() == null) {
                final LetterBitmap letterBitmap = new LetterBitmap(mActivity);
                Bitmap letterTile = letterBitmap.getLetterTile(playingMediaItem.getName(), playingMediaItem.getName(), COVER_IMAGE_SIZE, COVER_IMAGE_SIZE);
                imgCover.setImageBitmap(letterTile);
            } else {
                Glide.with(mActivity).load(playingMediaItem.getCoverImageUrl()).into(imgCover);
            }
        } else {
            this.rlSmallPLayer.setVisibility(View.GONE);
        }
    }

    private void setPlayerCallbacks() {
        universalPlayer.setPlayerStateListener(this);
        universalPlayer.setOnAutonomicTrackChangeCallback(new IOperationFinishCallback() {
            @Override
            public void operationFinished() {
                initPlayerUI();
            }
        });
    }

    private void runPositionUpdater() {
        playerPositionUpdater = (PlayerPositionUpdater) new PlayerPositionUpdater(new IOnPositionUpdatedCallback() {
            @Override
            public void poistionUpdated(int currentPoistion) {
                if (maxDuration < 0) {
                    MediaItem playingMediaItem = UniversalPlayer.getInstance().getPlayingMediaItem();
                    if (playingMediaItem instanceof Podcast) {
                        Track track = ((Podcast) playingMediaItem).getSelectedTrack();
                        maxDuration = MediaUtils.timeStringToLong(track.getDuration());
                    }
                    maxDuration = maxDuration > 0 ? maxDuration : FragmentPlayer.DEFAULT_RADIO_DURATIO;
                }
                int progress = (int) (currentPoistion * 100 / maxDuration);
                sbSmallPlayer.setProgress(progress);
            }

            @Override
            public void poistionUpdaterStoped() {

            }
        }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    @Override
    public void onStateChanged(UniversalPlayer.State state) {
        btnPlay.setImageResource(state == UniversalPlayer.State.PLAYING ? R.drawable.ic_pause_white : R.drawable.ic_play_white);
    }

    public void destroy() {
        mActivity = null;
    }

    public void onPause() {
        if (playerPositionUpdater != null) {
            playerPositionUpdater.cancel(false);
        }
        UniversalPlayer.getInstance().removeListeners();
    }

    public void onResume() {
        initPlayerUI();
        setPlayerCallbacks();
        runPositionUpdater();
    }

    @Override
    public void onClick(View view) {
        ActivityPlayer.openWithIntent(mActivity);
    }
} public interface ICustumziedBackPress {

    /**
     * @return true if you want to perform super  onBackPressed after Fragment onBackPressed or false otherwise
     */
    boolean onBackPressed();
} public interface IOperationFinishWithDataCallback {

    void operationFinished(Object data);
} public interface ISlidingMenuHolder{

    SlidingMenu getSlidingMenu();

    void setSlidingMenuHeader(String itemName);
} public interface IToolbarHolder {

    Toolbar getToolbar();

} public enum MediaItemType {

    DEFAULT, PODCAST, RADIO, PODCAST_DOWNLOADED, RADIO_SUBSCRIBED, RADIO_RECENT, PODCAST_FAVORITE, RADIO_SEARCH, PODCAST_SEARCH
} public class MediaViewpager extends ViewPager {

    private boolean enabled;

    public MediaViewpager(Context context) {
        super(context);
        this.enabled = true;
    }

    public MediaViewpager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
import android.app.Fragment;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.chickenkiller.upods2.R;
import com.chickenkiller.upods2.activity.ActivityMain;
import com.chickenkiller.upods2.controllers.adaperts.MediaPagesAdapter;
import com.chickenkiller.upods2.controllers.app.ProfileManager;
import com.chickenkiller.upods2.controllers.player.SmallPlayer;
import com.chickenkiller.upods2.interfaces.ICustumziedBackPress;
import com.chickenkiller.upods2.interfaces.IOperationFinishWithDataCallback;
import com.chickenkiller.upods2.interfaces.ISlidingMenuHolder;
import com.chickenkiller.upods2.interfaces.IToolbarHolder;
import com.chickenkiller.upods2.utils.enums.MediaItemType;
import com.chickenkiller.upods2.views.MediaViewpager;
import java.util.Calendar;
package com.chickenkiller.upods2.fragments;




/**
 * Created by Alon Zilberman on 8/8/15.
 */
public class FragmentMediaItemsGrid extends Fragment implements ICustumziedBackPress {

    private static final int CATEGORIES_FRAGMENT_POSITION = 3;
    public static final String LAST_ITEM_POSITION = "vp_last_postion";

    public static final String TAG;
    private MediaViewpager vpMedia;
    private MediaPagesAdapter mediaPagesAdapter;