public class EditNoteActivity extends SuperNoteActivity {
    @State
    protected long uid;

    protected Note noteToEdit;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        uid = getIntent().getLongExtra("uid", 0);

        noteToEdit = App.REALM.where(Note.class).equalTo("uid", uid).findFirst();
        if (noteToEdit == null) {
            // shit happens
            supportFinishAfterTransition();
        }

        currentPalette = PaletteUtils.get().palettes.get(noteToEdit.getPalette());

        super.onCreate(savedInstanceState);
        parentLayout.setVisibility(View.VISIBLE);
        noteTitle.setText(noteToEdit.getTitle());
        noteContent.setText(noteToEdit.getContent());
        setUiElementsColor(currentPalette, 0);
    }

    @Override
    public void onEnterAnimationComplete() {
        super.onEnterAnimationComplete();

        archive.post(new Runnable() {
            @Override
            public void run() {
                if (noteToEdit.getArchive()) {
                    archive.performClick();
                }
            }
        });

        reminder.post(new Runnable() {
            @Override
            public void run() {
                if (noteToEdit.getReminder()) {
                    reminder.performClick();
                }
            }
        });
    }

    // we gotta make sure the edited note makes sense before updating the view back in the main sheets
    private boolean assertNoteEdit(String title, String content, String palette, boolean isArchive, boolean isReminder) {
        return !noteToEdit.getTitle().equals(title) ||
                !noteToEdit.getContent().equals(content) ||
                !noteToEdit.getPalette().equals(palette) ||
                noteToEdit.getArchive() != isArchive ||
                noteToEdit.getReminder() != isReminder;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.existing_note, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                break;
            case R.id.delete:
                App.BUS.post(new NoteDeleted(noteToEdit));
                supportFinishAfterTransition();
                break;
            case R.id.share:
                String textToShare = noteTitle.getText().toString();
                textToShare += "\n\n";
                textToShare += noteContent.getText().toString();

                Intent sendIntent = new Intent();
                sendIntent.setAction(Intent.ACTION_SEND);
                sendIntent.putExtra(Intent.EXTRA_TEXT, textToShare);
                sendIntent.setType("text/plain");
                startActivity(Intent.createChooser(sendIntent, App.CONTEXT.getString(R.string.intent_chooser_title)));
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onDestroy() {
        // we check if the Realm object is valid before trying to mess with it
        if (noteToEdit.isValid()) {
            String title = noteTitle.getText().toString();
            String content = noteContent.getText().toString();
            String palette = currentPalette.getName();
            boolean isArchive = archive.isSelected();
            boolean isReminder = reminder.isSelected();

            if (assertNoteEdit(title, content, palette, isArchive, isReminder)) {
                App.REALM.beginTransaction();
                noteToEdit.setDate(System.currentTimeMillis());
                noteToEdit.setTitle(title);
                noteToEdit.setContent(content);
                noteToEdit.setPalette(palette);
                noteToEdit.setArchive(isArchive);
                noteToEdit.setReminder(isReminder);
                App.REALM.commitTransaction();

                App.BUS.post(new NoteUpdated(noteToEdit));
            }
        }

        App.BUS.unregister(this);
        super.onDestroy();
    }
} public class MainActivity extends SuperAppCompatActivity {
    public static final String PAST = App.CONTEXT.getString(R.string.past);
    public static final String PRESENT = App.CONTEXT.getString(R.string.present);
    public static final String FUTURE = App.CONTEXT.getString(R.string.future);

    @BindView(R.id.parent_layout)
    protected FrameLayout parentLayout;
    @BindView(R.id.toolbar)
    protected Toolbar toolbar;
    @BindView(R.id.tablayout)
    protected TabLayout tabLayout;
    @BindView(R.id.viewpager)
    protected ViewPager viewPager;
    @BindView(R.id.try_writing_a_note)
    protected TextView tryWritingAnote;
    @BindView(R.id.fab)
    protected FloatingActionButton fab;
    @BindView(R.id.bottom_fab_bar)
    protected FrameLayout bottomFabBar;

    private static String[] tabs;

    static {
        tabs = new String[]{
                PAST,
                PRESENT,
                FUTURE
        };
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        App.BUS.register(this);

        setSupportActionBar(toolbar);

        viewPager.setOffscreenPageLimit(3);
        viewPager.setAdapter(fragmentPagerAdapter);
        tabLayout.setupWithViewPager(viewPager);

        // we want custom fonts on the tabs textViews
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            tabLayout.getTabAt(i).setCustomView(R.layout.tab_layout_item);
        }

        viewPager.setCurrentItem(1);

        // mutate the FAB's colour!
        new Gaia.Builder()
                .setName(GaiaUtils.FAB)
                .setMutativeView(new WeakReference<Object>(fab))
                .setColorToScale(fab.getBackgroundTintList().getDefaultColor())
                .build();
    }

    private void animateOpenBottomFabSheet() {
        if (bottomFabBar != null && bottomFabBar.getVisibility() == View.INVISIBLE) {
            final int[] xy = ViewUtils.viewCoordinates(fab);

            Animator animator = ViewAnimationUtils.createCircularReveal(
                    bottomFabBar,
                    (xy[0] + (fab.getMeasuredWidth() >> 1)),
                    -bottomFabBar.getHeight(),
                    UIUtils.convertDpToPixel(56f, App.CONTEXT),
                    Math.max(bottomFabBar.getWidth(), bottomFabBar.getHeight()));
            animator.setDuration(500);
            animator.setStartDelay(7000);
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (fab != null) {
                        fab.setVisibility(View.GONE);
                    }

                    if (bottomFabBar != null) {
                        bottomFabBar.setVisibility(View.VISIBLE);
                    }
                }
            });
            animator.start();
        }
    }

    private void animateCloseBottomFabSheet() {
        if (bottomFabBar != null && bottomFabBar.getVisibility() == View.VISIBLE) {
            final int[] xy = ViewUtils.viewCoordinates(fab);

            Animator animator = ViewAnimationUtils.createCircularReveal(
                    bottomFabBar,
                    (xy[0] + (fab.getMeasuredWidth() >> 1)),
                    -bottomFabBar.getHeight(),
                    Math.max(bottomFabBar.getWidth(), bottomFabBar.getHeight()),
                    0);
            animator.setDuration(500);
            animator.setStartDelay(500);
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    if (fab != null) {
                        fab.setVisibility(View.VISIBLE);
                    }
                    if (bottomFabBar != null) {
                        bottomFabBar.setVisibility(View.INVISIBLE);
                    }
                }
            });
            animator.start();
        }
    }

    private FragmentPagerAdapter fragmentPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new PastFragment();
                case 1:
                    return new PresentFragment();
                case 2:
                    return new FutureFragment();
                default:
                    return null;
            }
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabs[position];
        }

        @Override
        public int getCount() {
            return tabs.length;
        }
    };

    @Subscribe
    public void onPast(Past past) {
        viewPager.setCurrentItem(0);
    }

    @Subscribe
    public void onPresent(Present present) {
        viewPager.setCurrentItem(1);
    }

    @Subscribe
    public void onFuture(Future future) {
        viewPager.setCurrentItem(2);
    }

    @OnClick({R.id.fab, R.id.bottom_fab_bar})
    protected void onFabClick(final View newNoteView) {
        Intent newNote = new Intent(this, NewNoteActivity.class);

        // we want the right coordinates to start the circular reveal
        int[] xy = ViewUtils.viewCoordinates(fab);
        newNote.putExtra("fabX", (xy[0] + (fab.getMeasuredWidth() >> 1)));
        newNote.putExtra("fabY", (xy[1] + (fab.getMeasuredHeight() >> 1)));

        startActivity(newNote);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);

        // Liam would kill me if the (info) button was not coloured the same as the tabs titles
        menu.findItem(R.id.about).getIcon().setTint(ContextCompat.getColor(this,
                android.support.v7.appcompat.R.color.secondary_text_default_material_light));
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.about:
                startActivity(new Intent(this, AboutActivity.class),
                        ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (fab.getVisibility() == View.VISIBLE) {
            fab.startAnimation(AnimationUtils.loadAnimation(App.CONTEXT, R.anim.scale_fab_in));
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        App.SENSOR_AMBIENT_LIGHT.stopSensor();
    }

    @Override
    protected void onResume() {
        super.onResume();
        App.SENSOR_AMBIENT_LIGHT.startSensor();
        App.MAIN_THREAD.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (NoteUtils.hasNotes()) {
                    animateCloseBottomFabSheet();
                } else {
                    animateOpenBottomFabSheet();
                }

                App.MAIN_THREAD.removeCallbacks(this);
            }
        }, 250);
    }

    @Override
    protected void onDestroy() {
        App.BUS.unregister(this);
        super.onDestroy();
    }
} public class App extends Application {
    public static Context CONTEXT;
    public static Resources RESOURCES;
    public static Handler MAIN_THREAD;
    public static TinyBus BUS;
    public static AmbientLight SENSOR_AMBIENT_LIGHT;
    public static List<Gaia> GAIAS;
    public static Realm REALM;

    public static void LOG(Object msg) {
        do {
            Log.d(CONTEXT.getPackageName(), String.valueOf(msg));
        } while (false);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return;
        }
        LeakCanary.install(this);
        Realm.init(this);

        CONTEXT = this;
        RESOURCES = getResources();
        MAIN_THREAD = new Handler(getMainLooper());
        BUS = TinyBus.from(this);
        SENSOR_AMBIENT_LIGHT = new AmbientLight();
        GAIAS = new ArrayList<>();
        REALM = Realm.getDefaultInstance();
    }
} public class Future {
} public class MoveNoteToFrontRow {
    private Note note;
    private int layoutPosition;

    public MoveNoteToFrontRow(Note note, int layoutPosition) {
        this.note = note;
        this.layoutPosition = layoutPosition;
    }

    public Note getNote() {
        return note;
    }

    public int getLayoutPosition() {
        return layoutPosition;
    }
} public class NewNoteSaved {
    private Note note;

    public NewNoteSaved(Note note) {
        this.note = note;
    }

    public Note getNote() {
        return note;
    }
} public class NotesCount {
    private int size;

    public NotesCount(int size) {
        this.size = size;
    }

    public int getSize() {
        return size;
    }
} public class Present {
} public class Note extends RealmObject {
    @PrimaryKey
    private long uid;
    @Index
    private long date;
    private String title;
    private String content;
    private String palette;
    private boolean archive;
    private boolean reminder;
    private long reminderDate;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getPalette() {
        return palette;
    }

    public void setPalette(String palette) {
        this.palette = palette;
    }

    public long getDate() {
        return date;
    }

    public void setDate(long date) {
        this.date = date;
    }

    public long getUid() {
        return uid;
    }

    public boolean getArchive() {
        return archive;
    }

    public void setArchive(boolean archive) {
        this.archive = archive;

        if (archive && getReminder()) {
            setReminder(false);
        }
    }

    public boolean getReminder() {
        return reminder;
    }

    public void setReminder(boolean reminder) {
        this.reminder = reminder;

        if (reminder && getArchive()) {
            setArchive(false);
        }
    }

    public long getReminderDate() {
        return reminderDate;
    }

    public void setReminderDate(long reminderDate) {
        this.reminderDate = reminderDate;
    }
} public class NoteItem extends AbstractItem<NoteItem, NoteItem.ViewHolder> {
    private final ViewHolderFactory<? extends ViewHolder> FACTORY = new ItemFactory();
    private Note note;
    private ViewHolder viewHolder;

    public NoteItem(Note note) {
        this.note = note;
    }

    private static class ItemFactory implements ViewHolderFactory<ViewHolder> {
        public ViewHolder create(View v) {
            return new ViewHolder(v);
        }
    }

    @Override
    public ViewHolderFactory<? extends ViewHolder> getFactory() {
        return FACTORY;
    }

    @Override
    public int getType() {
        return R.id.parent_layout;
    }

    @Override
    public int getLayoutRes() {
        return R.layout.note;
    }

    public ViewHolder getViewHolder() {
        return viewHolder;
    }

    private void setViewHolder(ViewHolder viewHolder) {
        this.viewHolder = viewHolder;
    }

    private Note getNote() {
        return note;
    }

    @Override
    public void bindView(ViewHolder viewHolder, List payloads) {
        super.bindView(viewHolder, payloads);

        viewHolder.setNote(getNote());
        setViewHolder(viewHolder);
        setUi(viewHolder);

        if (!App.BUS.hasRegistered(viewHolder)) {
            App.BUS.register(viewHolder);
        }
    }

    private void setUi(ViewHolder holder) {
        if (((ColorDrawable) holder.parentLayout.getBackground()).getColor() != holder.getPalette().getPrimary()) {
            holder.parentLayout.setBackgroundColor(holder.getPalette().getPrimary());
        }
        if (!holder.title.getText().toString().equals(holder.getNote().getTitle())) {
            holder.title.setText(holder.getNote().getTitle());
        }
        if (holder.title.getCurrentTextColor() != holder.getPalette().getTextColor()) {
            holder.title.setTextColor(holder.getPalette().getTextColor());
        }
        if (!holder.content.getText().toString().equals(holder.getNote().getContent())) {
            holder.content.setText(holder.getNote().getContent());
        }
        if (holder.content.getCurrentTextColor() != holder.getPalette().getTextColor()) {
            holder.content.setTextColor(holder.getPalette().getTextColor());
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.parent_layout)
        protected ForegroundLinearLayout parentLayout;
        @BindView(R.id.title)
        protected TextView title;
        @BindView(R.id.content)
        protected TextView content;

        protected Note note;
        protected Palette palette;

        public ViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
        }

        public Note getNote() {
            return note;
        }

        public Palette getPalette() {
            return palette;
        }

        public void setNote(Note note) {
            this.note = note;
            this.palette = PaletteUtils.get().palettes.get(note.getPalette());

            new Gaia.Builder()
                    .setName(getNote().getTitle() + "_" + GaiaUtils.NOTE_PARENT_LAYOUT)
                    .setMutativeView(new WeakReference<Object>(parentLayout))
                    .setColorToScale(palette.getPrimary())
                    .build();

            new Gaia.Builder()
                    .setName(getNote().getTitle() + "_" + GaiaUtils.NOTE_TITLE)
                    .setMutativeView(new WeakReference<Object>(title))
                    .setColorToScale(palette.getTextColor())
                    .build();

            new Gaia.Builder()
                    .setName(getNote().getTitle() + "_" + GaiaUtils.NOTE_CONTENT)
                    .setMutativeView(new WeakReference<Object>(content))
                    .setColorToScale(palette.getTextColor())
                    .build();
        }

        @Subscribe
        public void onNoteUpdated(NoteUpdated updatedNote) {
            if (note != null && note.isValid() && note.getUid() == updatedNote.getEditedNote().getUid()) {
                setNote(updatedNote.getEditedNote());
                parentLayout.setBackgroundColor(getPalette().getPrimary());
                title.setText(getNote().getTitle());
                title.setTextColor(getPalette().getTextColor());
                content.setText(getNote().getContent());
                content.setTextColor(getPalette().getTextColor());

                App.BUS.post(new NoteUpdatingEvent(updatedNote.getEditedNote(), getLayoutPosition()));
            }
        }
    }
} public class RecyclerViewUtils {
    public static class SpacesItemDecoration extends RecyclerView.ItemDecoration {
        private int space;

        public SpacesItemDecoration(int space) {
            this.space = space;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            outRect.left = space;
            outRect.right = space;
            outRect.bottom = space;
            outRect.top = space;
        }
    }
}
import android.animation.ValueAnimator;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.IAdapter;
import com.mikepenz.fastadapter.adapters.FastItemAdapter;
import com.mikepenz.materialize.util.UIUtils;
import java.util.Collections;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import de.halfbit.tinybus.Subscribe;
import liam.franco.selene.R;
import liam.franco.selene.activities.EditNoteActivity;
import liam.franco.selene.activities.MainActivity;
import liam.franco.selene.application.App;
import liam.franco.selene.bus.Future;
import liam.franco.selene.bus.MoveNoteToFrontRow;
import liam.franco.selene.bus.NewNoteSaved;
import liam.franco.selene.bus.NotesCount;
import liam.franco.selene.bus.Present;
import liam.franco.selene.modules.Note;
import liam.franco.selene.ui.NoteItem;
import liam.franco.selene.utils.RecyclerViewUtils;
/*
 * Copyright 2016 Francisco Franco & Liam Spradlin
 *
 * 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 liam.franco.selene.fragments;





public class SuperNotesFragment extends Fragment {
    @BindView(R.id.parent_layout)
    protected FrameLayout parentLayout;
    @BindView(R.id.recycler_view)
    protected RecyclerView recyclerView;
    @BindView(R.id.empty_view)
    protected LinearLayout emptyView;

    @LayoutRes
    private int resId;

    private FastItemAdapter<NoteItem> adapter;
    private String tabTitle;
    private Unbinder unbinder;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View layout = inflater.inflate(resId, container, false);
        unbinder = ButterKnife.bind(this, layout);
        App.BUS.register(this);

        adapter = new FastItemAdapter<>();
        recyclerView.setAdapter(adapter);
        RecyclerView.ItemDecoration itemDecoration
                = new RecyclerViewUtils.SpacesItemDecoration((int) UIUtils.convertDpToPixel(4, App.CONTEXT));
        recyclerView.addItemDecoration(itemDecoration);

        adapter.withOnClickListener(new FastAdapter.OnClickListener<NoteItem>() {
            @Override
            public boolean onClick(View v, IAdapter<NoteItem> adapter, NoteItem item, int position) {
                Intent newNoteActivity = new Intent(getActivity(), EditNoteActivity.class);
                newNoteActivity.putExtra("uid", item.getViewHolder().getNote().getUid());

                startActivity(newNoteActivity);

                return true;
            }
        });

        return layout;
    }

    public void addNote(Note note) {
        if (getAdapter() != null) {
            getAdapter().add(0, new NoteItem(note));
        }
    }

    public void updateNote(int oldPosition) {
        if (getAdapter() != null && getAdapter().getAdapterItemCount() > 0) {
            Collections.swap(getAdapter().getAdapterItems(), oldPosition, 0);
            getAdapter().notifyAdapterItemMoved(oldPosition, 0);
        }
    }

    public FastItemAdapter<NoteItem> getAdapter() {
        return adapter;
    }

    public void setResId(@LayoutRes int resId) {
        this.resId = resId;
    }

    public void setEmptyView() {
        emptyView.setVisibility(getAdapter().getAdapterItemCount() > 0 ? View.GONE : View.VISIBLE);
    }

    public String getTabTitle() {
        return tabTitle;
    }

    public void setTabTitle(String tabTitle) {
        this.tabTitle = tabTitle;
    }

    @Subscribe
    public void newNoteCreated(NewNoteSaved newNote) {
        if (newNote.getNote().getArchive()) {
            if (getTabTitle().equals(MainActivity.PAST)) {
                addNote(newNote.getNote());
            }

        } else if (newNote.getNote().getReminder()) {
            if (getTabTitle().equals(MainActivity.FUTURE)) {
                addNote(newNote.getNote());
                App.BUS.post(new Future());