package com.mikepenz.materialdrawer;

import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.holder.ColorHolder;
import com.mikepenz.materialdrawer.holder.DimenHolder;
import com.mikepenz.materialdrawer.holder.ImageHolder;
import com.mikepenz.materialdrawer.holder.StringHolder;
import com.mikepenz.materialdrawer.icons.MaterialDrawerFont;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import com.mikepenz.materialdrawer.util.DrawerImageLoader;
import com.mikepenz.materialdrawer.util.DrawerUIUtils;
import com.mikepenz.materialdrawer.view.BezelImageView;
import com.mikepenz.materialize.util.UIUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.Guideline;
import androidx.core.view.ViewCompat;
import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

/**
 * Created by mikepenz on 23.05.15.
 */
public class AccountHeaderBuilder {
    // global references to views we need later
    protected Guideline mStatusBarGuideline;
    protected View mAccountHeader;
    protected GifImageView mAccountHeaderBackground;
    protected BezelImageView mCurrentProfileView;
    protected ImageView mAccountSwitcherArrow;
    protected TextView mCurrentProfileName;
    protected TextView mCurrentProfileEmail;
    protected BezelImageView mProfileFirstView;
    protected BezelImageView mProfileSecondView;
    protected BezelImageView mProfileThirdView;

    // global references to the profiles
    protected IProfile mCurrentProfile;
    protected IProfile mProfileFirst;
    protected IProfile mProfileSecond;
    protected IProfile mProfileThird;


    // global stuff
    protected boolean mSelectionListShown = false;
    protected int mAccountHeaderTextSectionBackgroundResource = -1;

    // the activity to use
    protected Activity mActivity;

    /**
     * Pass the activity you use the drawer in ;)
     *
     * @param activity
     * @return
     */
    public AccountHeaderBuilder withActivity(@NonNull Activity activity) {
        this.mActivity = activity;
        return this;
    }

    // defines if we use the compactStyle
    protected boolean mCompactStyle = false;

    /**
     * Defines if we should use the compact style for the header.
     *
     * @param compactStyle
     * @return
     */
    public AccountHeaderBuilder withCompactStyle(boolean compactStyle) {
        this.mCompactStyle = compactStyle;
        return this;
    }

    // the typeface used for textViews within the AccountHeader
    protected Typeface mTypeface;

    // the typeface used for name textView only. overrides mTypeface
    protected Typeface mNameTypeface;

    // the typeface used for email textView only. overrides mTypeface
    protected Typeface mEmailTypeface;

    /**
     * Define the typeface which will be used for all textViews in the AccountHeader
     *
     * @param typeface
     * @return
     */
    public AccountHeaderBuilder withTypeface(@NonNull Typeface typeface) {
        this.mTypeface = typeface;
        return this;
    }

    /**
     * Define the typeface which will be used for name textView in the AccountHeader.
     * Overrides typeface supplied to {@link AccountHeaderBuilder#withTypeface(android.graphics.Typeface)}
     *
     * @param typeface
     * @return
     * @see #withTypeface(android.graphics.Typeface)
     */
    public AccountHeaderBuilder withNameTypeface(@NonNull Typeface typeface) {
        this.mNameTypeface = typeface;
        return this;
    }

    /**
     * Define the typeface which will be used for email textView in the AccountHeader.
     * Overrides typeface supplied to {@link AccountHeaderBuilder#withTypeface(android.graphics.Typeface)}
     *
     * @param typeface
     * @return
     * @see #withTypeface(android.graphics.Typeface)
     */
    public AccountHeaderBuilder withEmailTypeface(@NonNull Typeface typeface) {
        this.mEmailTypeface = typeface;
        return this;
    }

    // set the account header height
    protected DimenHolder mHeight;

    /**
     * set the height for the header
     *
     * @param heightPx
     * @return
     */
    public AccountHeaderBuilder withHeightPx(int heightPx) {
        this.mHeight = DimenHolder.fromPixel(heightPx);
        return this;
    }


    /**
     * set the height for the header
     *
     * @param heightDp
     * @return
     */
    public AccountHeaderBuilder withHeightDp(int heightDp) {
        this.mHeight = DimenHolder.fromDp(heightDp);
        return this;
    }

    /**
     * set the height for the header by resource
     *
     * @param heightRes
     * @return
     */
    public AccountHeaderBuilder withHeightRes(@DimenRes int heightRes) {
        this.mHeight = DimenHolder.fromResource(heightRes);
        return this;
    }

    //the background color for the slider
    protected ColorHolder mTextColor;

    /**
     * set the background for the slider as color
     *
     * @param textColor
     * @return
     */
    public AccountHeaderBuilder withTextColor(@ColorInt int textColor) {
        this.mTextColor = ColorHolder.fromColor(textColor);
        return this;
    }

    /**
     * set the background for the slider as resource
     *
     * @param textColorRes
     * @return
     */
    public AccountHeaderBuilder withTextColorRes(@ColorRes int textColorRes) {
        this.mTextColor = ColorHolder.fromColorRes(textColorRes);
        return this;
    }

    //the current selected profile is visible in the list
    protected boolean mCurrentHiddenInList = false;

    /**
     * hide the current selected profile from the list
     *
     * @param currentProfileHiddenInList
     * @return
     */
    public AccountHeaderBuilder withCurrentProfileHiddenInList(boolean currentProfileHiddenInList) {
        mCurrentHiddenInList = currentProfileHiddenInList;
        return this;
    }

    //set to hide the first or second line
    protected boolean mSelectionFirstLineShown = true;
    protected boolean mSelectionSecondLineShown = true;

    /**
     * set this to false if you want to hide the first line of the selection box in the header (first line would be the name)
     *
     * @param selectionFirstLineShown
     * @return
     * @deprecated replaced by {@link #withSelectionFirstLineShown}
     */
    @Deprecated
    public AccountHeaderBuilder withSelectionFistLineShown(boolean selectionFirstLineShown) {
        this.mSelectionFirstLineShown = selectionFirstLineShown;
        return this;
    }

    /**
     * set this to false if you want to hide the first line of the selection box in the header (first line would be the name)
     *
     * @param selectionFirstLineShown
     * @return
     */
    public AccountHeaderBuilder withSelectionFirstLineShown(boolean selectionFirstLineShown) {
        this.mSelectionFirstLineShown = selectionFirstLineShown;
        return this;
    }

    /**
     * set this to false if you want to hide the second line of the selection box in the header (second line would be the e-mail)
     *
     * @param selectionSecondLineShown
     * @return
     */
    public AccountHeaderBuilder withSelectionSecondLineShown(boolean selectionSecondLineShown) {
        this.mSelectionSecondLineShown = selectionSecondLineShown;
        return this;
    }


    //set one of these to define the text in the first or second line with in the account selector
    protected String mSelectionFirstLine;
    protected String mSelectionSecondLine;

    /**
     * set this to define the first line in the selection area if there is no profile
     * note this will block any values from profiles!
     *
     * @param selectionFirstLine
     * @return
     */
    public AccountHeaderBuilder withSelectionFirstLine(String selectionFirstLine) {
        this.mSelectionFirstLine = selectionFirstLine;
        return this;
    }

    /**
     * set this to define the second line in the selection area if there is no profile
     * note this will block any values from profiles!
     *
     * @param selectionSecondLine
     * @return
     */
    public AccountHeaderBuilder withSelectionSecondLine(String selectionSecondLine) {
        this.mSelectionSecondLine = selectionSecondLine;
        return this;
    }

    // set no divider below the header
    protected boolean mPaddingBelowHeader = true;

    /**
     * Set this to false if you want no padding below the Header
     *
     * @param paddingBelowHeader
     * @return
     */
    public AccountHeaderBuilder withPaddingBelowHeader(boolean paddingBelowHeader) {
        this.mPaddingBelowHeader = paddingBelowHeader;
        return this;
    }

    // set no divider below the header
    protected boolean mDividerBelowHeader = true;

    /**
     * Set this to false if you want no divider below the Header
     *
     * @param dividerBelowHeader
     * @return
     */
    public AccountHeaderBuilder withDividerBelowHeader(boolean dividerBelowHeader) {
        this.mDividerBelowHeader = dividerBelowHeader;
        return this;
    }

    // set non translucent statusBar mode
    protected boolean mTranslucentStatusBar = true;

    /**
     * Set or disable this if you use a translucent statusbar
     *
     * @param translucentStatusBar
     * @return
     */
    public AccountHeaderBuilder withTranslucentStatusBar(boolean translucentStatusBar) {
        this.mTranslucentStatusBar = translucentStatusBar;
        return this;
    }

    //the background for the header
    protected ImageHolder mHeaderBackground;

    /**
     * set the background for the slider as color
     *
     * @param headerBackground
     * @return
     */
    public AccountHeaderBuilder withHeaderBackground(Drawable headerBackground) {
        this.mHeaderBackground = new ImageHolder(headerBackground);
        return this;
    }

    /**
     * set the background for the header as resource
     *
     * @param headerBackgroundRes
     * @return
     */
    public AccountHeaderBuilder withHeaderBackground(@DrawableRes int headerBackgroundRes) {
        this.mHeaderBackground = new ImageHolder(headerBackgroundRes);
        return this;
    }

    /**
     * set the background for the header as file name
     *
     * @param headerBackgroundPath
     * @return
     */
    public AccountHeaderBuilder withHeaderBackground(String headerBackgroundPath) {
        try {
            if (headerBackgroundPath.endsWith(".gif")) {
                this.mHeaderBackground = new ImageHolder(new GifDrawable(headerBackgroundPath));
            }
            else {
                this.mHeaderBackground = new ImageHolder(Uri.parse(headerBackgroundPath));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return this;
    }

    /**
     * set the background for the header via the ImageHolder class
     *
     * @param headerBackground
     * @return
     */
    public AccountHeaderBuilder withHeaderBackground(ImageHolder headerBackground) {
        this.mHeaderBackground = headerBackground;
        return this;
    }

    //background scale type
    protected ImageView.ScaleType mHeaderBackgroundScaleType = null;

    /**
     * define the ScaleType for the header background
     *
     * @param headerBackgroundScaleType
     * @return
     */
    public AccountHeaderBuilder withHeaderBackgroundScaleType(ImageView.ScaleType headerBackgroundScaleType) {
        this.mHeaderBackgroundScaleType = headerBackgroundScaleType;
        return this;
    }

    //profile images in the header are shown or not
    protected boolean mProfileImagesVisible = true;

    /**
     * define if the profile images in the header are shown or not
     *
     * @param profileImagesVisible
     * @return
     */
    public AccountHeaderBuilder withProfileImagesVisible(boolean profileImagesVisible) {
        this.mProfileImagesVisible = profileImagesVisible;
        return this;
    }

    //only the main profile image is visible
    protected boolean mOnlyMainProfileImageVisible = false;

    /**
     * define if only the main (current selected) profile image should be visible
     *
     * @param onlyMainProfileImageVisible
     * @return
     */
    public AccountHeaderBuilder withOnlyMainProfileImageVisible(boolean onlyMainProfileImageVisible) {
        this.mOnlyMainProfileImageVisible = onlyMainProfileImageVisible;
        return this;
    }

    //show small profile images but hide MainProfileImage
    protected boolean mOnlySmallProfileImagesVisible = false;

    /**
     * define if only the small profile images should be visible
     *
     * @param onlySmallProfileImagesVisible
     * @return
     */
    public AccountHeaderBuilder withOnlySmallProfileImagesVisible(boolean onlySmallProfileImagesVisible) {
        this.mOnlySmallProfileImagesVisible = onlySmallProfileImagesVisible;
        return this;
    }

    //close the drawer after a profile was clicked in the list
    protected Boolean mCloseDrawerOnProfileListClick = null;

    /**
     * define if the drawer should close if the user clicks on a profile item if the selection list is shown
     *
     * @param closeDrawerOnProfileListClick
     * @return
     */
    public AccountHeaderBuilder withCloseDrawerOnProfileListClick(boolean closeDrawerOnProfileListClick) {
        this.mCloseDrawerOnProfileListClick = closeDrawerOnProfileListClick;
        return this;
    }

    //reset the drawer list to the main drawer list after the profile was clicked in the list
    protected boolean mResetDrawerOnProfileListClick = true;

    /**
     * define if the drawer selection list should be reseted after the user clicks on a profile item if the selection list is shown
     *
     * @param resetDrawerOnProfileListClick
     * @return
     */
    public AccountHeaderBuilder withResetDrawerOnProfileListClick(boolean resetDrawerOnProfileListClick) {
        this.mResetDrawerOnProfileListClick = resetDrawerOnProfileListClick;
        return this;
    }

    // set the profile images clickable or not
    protected boolean mProfileImagesClickable = true;

    /**
     * enable or disable the profile images to be clickable
     *
     * @param profileImagesClickable
     * @return
     */
    public AccountHeaderBuilder withProfileImagesClickable(boolean profileImagesClickable) {
        this.mProfileImagesClickable = profileImagesClickable;
        return this;
    }

    // set to use the alternative profile header switching
    protected boolean mAlternativeProfileHeaderSwitching = false;

    /**
     * enable the alternative profile header switching
     *
     * @param alternativeProfileHeaderSwitching
     * @return
     */
    public AccountHeaderBuilder withAlternativeProfileHeaderSwitching(boolean alternativeProfileHeaderSwitching) {
        this.mAlternativeProfileHeaderSwitching = alternativeProfileHeaderSwitching;
        return this;
    }

    // enable 3 small header previews
    protected boolean mThreeSmallProfileImages = false;

    /**
     * enable the extended profile icon view with 3 small header images instead of two
     *
     * @param threeSmallProfileImages
     * @return
     */
    public AccountHeaderBuilder withThreeSmallProfileImages(boolean threeSmallProfileImages) {
        this.mThreeSmallProfileImages = threeSmallProfileImages;
        return this;
    }

    //the delay which is waited before the drawer is closed
    protected int mOnProfileClickDrawerCloseDelay = 100;

    /**
     * Define the delay for the drawer close operation after a click.
     * This is a small trick to improve the speed (and remove lag) if you open a new activity after a DrawerItem
     * was selected.
     * NOTE: Disable this by passing -1
     *
     * @param onProfileClickDrawerCloseDelay the delay in MS (-1 to disable)
     * @return
     */
    public AccountHeaderBuilder withOnProfileClickDrawerCloseDelay(int onProfileClickDrawerCloseDelay) {
        this.mOnProfileClickDrawerCloseDelay = onProfileClickDrawerCloseDelay;
        return this;
    }

    // the onAccountHeaderProfileImageListener to set
    protected AccountHeader.OnAccountHeaderProfileImageListener mOnAccountHeaderProfileImageListener;

    /**
     * set click / longClick listener for the header images
     *
     * @param onAccountHeaderProfileImageListener
     * @return
     */
    public AccountHeaderBuilder withOnAccountHeaderProfileImageListener(AccountHeader.OnAccountHeaderProfileImageListener onAccountHeaderProfileImageListener) {
        this.mOnAccountHeaderProfileImageListener = onAccountHeaderProfileImageListener;
        return this;
    }

    // the onAccountHeaderSelectionListener to set
    protected AccountHeader.OnAccountHeaderSelectionViewClickListener mOnAccountHeaderSelectionViewClickListener;

    /**
     * set a onSelection listener for the selection box
     *
     * @param onAccountHeaderSelectionViewClickListener
     * @return
     */
    public AccountHeaderBuilder withOnAccountHeaderSelectionViewClickListener(AccountHeader.OnAccountHeaderSelectionViewClickListener onAccountHeaderSelectionViewClickListener) {
        this.mOnAccountHeaderSelectionViewClickListener = onAccountHeaderSelectionViewClickListener;
        return this;
    }

    //set the selection list enabled if there is only a single profile
    protected boolean mSelectionListEnabledForSingleProfile = true;

    /**
     * enable or disable the selection list if there is only a single profile
     *
     * @param selectionListEnabledForSingleProfile
     * @return
     */
    public AccountHeaderBuilder withSelectionListEnabledForSingleProfile(boolean selectionListEnabledForSingleProfile) {
        this.mSelectionListEnabledForSingleProfile = selectionListEnabledForSingleProfile;
        return this;
    }

    //set the selection enabled disabled
    protected boolean mSelectionListEnabled = true;

    /**
     * enable or disable the selection list
     *
     * @param selectionListEnabled
     * @return
     */
    public AccountHeaderBuilder withSelectionListEnabled(boolean selectionListEnabled) {
        this.mSelectionListEnabled = selectionListEnabled;
        return this;
    }

    // the drawerLayout to use
    protected View mAccountHeaderContainer;

    /**
     * You can pass a custom view for the drawer lib. note this requires the same structure as the drawer.xml
     *
     * @param accountHeader
     * @return
     */
    public AccountHeaderBuilder withAccountHeader(@NonNull View accountHeader) {
        this.mAccountHeaderContainer = accountHeader;
        return this;
    }

    /**
     * You can pass a custom layout for the drawer lib. see the drawer.xml in layouts of this lib on GitHub
     *
     * @param resLayout
     * @return
     */
    public AccountHeaderBuilder withAccountHeader(@LayoutRes int resLayout) {
        if (mActivity == null) {
            throw new RuntimeException("please pass an activity first to use this call");
        }

        if (resLayout != -1) {
            this.mAccountHeaderContainer = mActivity.getLayoutInflater().inflate(resLayout, null, false);
        } else {
            if (mCompactStyle) {
                this.mAccountHeaderContainer = mActivity.getLayoutInflater().inflate(R.layout.material_drawer_compact_header, null, false);
            } else {
                this.mAccountHeaderContainer = mActivity.getLayoutInflater().inflate(R.layout.material_drawer_header, null, false);
            }
        }

        return this;
    }

    // the profiles to display
    protected List<IProfile> mProfiles;

    /**
     * set the arrayList of DrawerItems for the drawer
     *
     * @param profiles
     * @return
     */
    public AccountHeaderBuilder withProfiles(@NonNull List<IProfile> profiles) {
        if (mDrawer != null) {
            mDrawer.mDrawerBuilder.idDistributor.checkIds(profiles);
        }
        this.mProfiles = profiles;
        return this;
    }

    /**
     * add single ore more DrawerItems to the Drawer
     *
     * @param profiles
     * @return
     */
    public AccountHeaderBuilder addProfiles(@NonNull IProfile... profiles) {
        if (this.mProfiles == null) {
            this.mProfiles = new ArrayList<>();
        }
        if (mDrawer != null) {
            mDrawer.mDrawerBuilder.idDistributor.checkIds(profiles);
        }
        Collections.addAll(this.mProfiles, profiles);

        return this;
    }

    // the click listener to be fired on profile or selection click
    protected AccountHeader.OnAccountHeaderListener mOnAccountHeaderListener;

    /**
     * add a listener for the accountHeader
     *
     * @param onAccountHeaderListener
     * @return
     */
    public AccountHeaderBuilder withOnAccountHeaderListener(AccountHeader.OnAccountHeaderListener onAccountHeaderListener) {
        this.mOnAccountHeaderListener = onAccountHeaderListener;
        return this;
    }

    //the on long click listener to be fired on profile longClick inside the list
    protected AccountHeader.OnAccountHeaderItemLongClickListener mOnAccountHeaderItemLongClickListener;

    /**
     * the on long click listener to be fired on profile longClick inside the list
     *
     * @param onAccountHeaderItemLongClickListener
     * @return
     */
    public AccountHeaderBuilder withOnAccountHeaderItemLongClickListener(AccountHeader.OnAccountHeaderItemLongClickListener onAccountHeaderItemLongClickListener) {
        this.mOnAccountHeaderItemLongClickListener = onAccountHeaderItemLongClickListener;
        return this;
    }

    // the drawer to set the AccountSwitcher for
    protected Drawer mDrawer;

    /**
     * @param drawer
     * @return
     */
    public AccountHeaderBuilder withDrawer(@NonNull Drawer drawer) {
        this.mDrawer = drawer;

        //set the top padding to 0 as this would happen when the AccountHeader is created during Drawer build time
        drawer.getRecyclerView().setPadding(drawer.getRecyclerView().getPaddingLeft(), 0, drawer.getRecyclerView().getPaddingRight(), drawer.getRecyclerView().getPaddingBottom());
        return this;
    }

    // savedInstance to restore state
    protected Bundle mSavedInstance;

    /**
     * create the drawer with the values of a savedInstance
     *
     * @param savedInstance
     * @return
     */
    public AccountHeaderBuilder withSavedInstance(Bundle savedInstance) {
        this.mSavedInstance = savedInstance;
        return this;
    }

    /**
     * helper method to set the height for the header!
     *
     * @param height
     */
    private void setHeaderHeight(int height) {
        if (mAccountHeaderContainer != null) {
            ViewGroup.LayoutParams params = mAccountHeaderContainer.getLayoutParams();
            if (params != null) {
                params.height = height;
                mAccountHeaderContainer.setLayoutParams(params);
            }

            View accountHeader = mAccountHeaderContainer.findViewById(R.id.material_drawer_account_header);
            if (accountHeader != null) {
                // TODO why is this null?
                params = accountHeader.getLayoutParams();
                if(params != null) {
                    params.height = height;
                    accountHeader.setLayoutParams(params);
                }
            }

            View accountHeaderBackground = mAccountHeaderContainer.findViewById(R.id.material_drawer_account_header_background);
            if (accountHeaderBackground != null) {
                params = accountHeaderBackground.getLayoutParams();
                params.height = height;
                accountHeaderBackground.setLayoutParams(params);
            }
        }
    }

    /**
     * a small helper to handle the selectionView
     *
     * @param on
     */
    private void handleSelectionView(IProfile profile, boolean on) {
        if (on) {
            if (Build.VERSION.SDK_INT >= 23) {
                mAccountHeaderContainer.setForeground(AppCompatResources.getDrawable(mAccountHeaderContainer.getContext(), mAccountHeaderTextSectionBackgroundResource));
            } else {
                // todo foreground thing?
            }
            mAccountHeaderContainer.setOnClickListener(onSelectionClickListener);
            mAccountHeaderContainer.setTag(R.id.material_drawer_profile_header, profile);
        } else {
            if (Build.VERSION.SDK_INT >= 23) {
                mAccountHeaderContainer.setForeground(null);
            } else {
                // TODO foreground reset
            }
            mAccountHeaderContainer.setOnClickListener(null);
        }
    }

    /**
     * method to build the header view
     *
     * @return
     */
    public AccountHeader build() {
        // if the user has not set a accountHeader use the default one :D
        if (mAccountHeaderContainer == null) {
            withAccountHeader(-1);
        }

        // get the header view within the container
        mAccountHeader = mAccountHeaderContainer.findViewById(R.id.material_drawer_account_header);
        mStatusBarGuideline = mAccountHeaderContainer.findViewById(R.id.material_drawer_statusbar_guideline);

        //the default min header height by default 148dp
        int defaultHeaderMinHeight = mActivity.getResources().getDimensionPixelSize(R.dimen.material_drawer_account_header_height);
        int statusBarHeight = UIUtils.getStatusBarHeight(mActivity, true);

        // handle the height for the header
        int height;
        if (mHeight != null) {
            height = mHeight.asPixel(mActivity);
        } else {
            if (mCompactStyle) {
                height = mActivity.getResources().getDimensionPixelSize(R.dimen.material_drawer_account_header_height_compact);
            } else {
                //calculate the header height by getting the optimal drawer width and calculating it * 9 / 16
                height = (int) (DrawerUIUtils.getOptimalDrawerWidth(mActivity) * AccountHeader.NAVIGATION_DRAWER_ACCOUNT_ASPECT_RATIO);

                //if we are lower than api 19 (>= 19 we have a translucentStatusBar) the height should be a bit lower
                //probably even if we are non translucent on > 19 devices?
                if (Build.VERSION.SDK_INT < 19) {
                    int tempHeight = height - statusBarHeight;
                    //if we are lower than api 19 we are not able to have a translucent statusBar so we remove the height of the statusBar from the padding
                    //to prevent display issues we only reduce the height if we still fit the required minHeight of 148dp (R.dimen.material_drawer_account_header_height)
                    //we remove additional 8dp from the defaultMinHeaderHeight as there is some buffer in the header and to prevent to large spacings
                    if (tempHeight > defaultHeaderMinHeight - UIUtils.convertDpToPixel(8, mActivity)) {
                        height = tempHeight;
                    }
                }
            }
        }

        // handle everything if we have a translucent status bar which only is possible on API >= 19
        if (mTranslucentStatusBar && Build.VERSION.SDK_INT >= 21) {
            mStatusBarGuideline.setGuidelineBegin(statusBarHeight);

            //in fact it makes no difference if we have a translucent statusBar or not. we want 9/16 just if we are not compact
            if (mCompactStyle) {
                height = height + statusBarHeight;
            } else if ((height - statusBarHeight) <= defaultHeaderMinHeight) {
                //if the height + statusBar of the header is lower than the required 148dp + statusBar we change the height to be able to display all the data
                height = defaultHeaderMinHeight + statusBarHeight;
            }
        }

        //set the height for the header
        setHeaderHeight(height);

        // get the background view
        mAccountHeaderBackground = (GifImageView) mAccountHeaderContainer.findViewById(R.id.material_drawer_account_header_background);
        // set the background
        ImageHolder.applyTo(mHeaderBackground, mAccountHeaderBackground, DrawerImageLoader.Tags.ACCOUNT_HEADER.name());

        if (mHeaderBackgroundScaleType != null) {
            mAccountHeaderBackground.setScaleType(mHeaderBackgroundScaleType);
        }

        // get the text color to use for the text section
        int textColor = ColorHolder.color(mTextColor, mActivity, R.attr.material_drawer_header_selection_text, R.color.material_drawer_header_selection_text);
        int subTextColor = ColorHolder.color(mTextColor, mActivity, R.attr.material_drawer_header_selection_subtext, R.color.material_drawer_header_selection_subtext);

        mAccountHeaderTextSectionBackgroundResource = UIUtils.getSelectableBackgroundRes(mActivity);
        handleSelectionView(mCurrentProfile, true);

        // set the arrow :D
        mAccountSwitcherArrow = mAccountHeaderContainer.findViewById(R.id.material_drawer_account_header_text_switcher);
        mAccountSwitcherArrow.setImageDrawable(new IconicsDrawable(mActivity, MaterialDrawerFont.Icon.mdf_arrow_drop_down).sizeRes(R.dimen.material_drawer_account_header_dropdown).paddingRes(R.dimen.material_drawer_account_header_dropdown_padding).color(subTextColor));

        //get the fields for the name
        mCurrentProfileView = mAccountHeader.findViewById(R.id.material_drawer_account_header_current);
        mCurrentProfileName = mAccountHeader.findViewById(R.id.material_drawer_account_header_name);
        mCurrentProfileEmail = mAccountHeader.findViewById(R.id.material_drawer_account_header_email);

        //set the typeface for the AccountHeader
        if (mNameTypeface != null) {
            mCurrentProfileName.setTypeface(mNameTypeface);
        } else if (mTypeface != null) {
            mCurrentProfileName.setTypeface(mTypeface);
        }

        if (mEmailTypeface != null) {
            mCurrentProfileEmail.setTypeface(mEmailTypeface);
        } else if (mTypeface != null) {
            mCurrentProfileEmail.setTypeface(mTypeface);
        }

        mCurrentProfileName.setTextColor(textColor);
        mCurrentProfileEmail.setTextColor(subTextColor);

        mProfileFirstView = mAccountHeader.findViewById(R.id.material_drawer_account_header_small_first);
        mProfileSecondView = mAccountHeader.findViewById(R.id.material_drawer_account_header_small_second);
        mProfileThirdView = mAccountHeader.findViewById(R.id.material_drawer_account_header_small_third);

        //calculate the profiles to set
        calculateProfiles();

        //process and build the profiles
        buildProfiles();

        // try to restore all saved values again
        if (mSavedInstance != null) {
            int selection = mSavedInstance.getInt(AccountHeader.BUNDLE_SELECTION_HEADER, -1);
            if (selection != -1) {
                //predefine selection (should be the first element
                if (mProfiles != null && (selection) > -1 && selection < mProfiles.size()) {
                    switchProfiles(mProfiles.get(selection));
                }
            }
        }

        //everything created. now set the header
        if (mDrawer != null) {
            mDrawer.setHeader(mAccountHeaderContainer, mPaddingBelowHeader, mDividerBelowHeader);
        }

        //forget the reference to the activity
        mActivity = null;

        return new AccountHeader(this);
    }

    /**
     * helper method to calculate the order of the profiles
     */
    protected void calculateProfiles() {
        if (mProfiles == null) {
            mProfiles = new ArrayList<>();
        }

        if (mCurrentProfile == null) {
            int setCount = 0;
            int size = mProfiles.size();
            for (int i = 0; i < size; i++) {
                if (mProfiles.size() > i && mProfiles.get(i).isSelectable()) {
                    if (setCount == 0 && (mCurrentProfile == null)) {
                        mCurrentProfile = mProfiles.get(i);
                    } else if (setCount == 1 && (mProfileFirst == null)) {
                        mProfileFirst = mProfiles.get(i);
                    } else if (setCount == 2 && (mProfileSecond == null)) {
                        mProfileSecond = mProfiles.get(i);
                    } else if (setCount == 3 && (mProfileThird == null)) {
                        mProfileThird = mProfiles.get(i);
                    }
                    setCount++;
                }
            }

            return;
        }

        IProfile[] previousActiveProfiles = new IProfile[]{
                mCurrentProfile,
                mProfileFirst,
                mProfileSecond,
                mProfileThird
        };

        IProfile[] newActiveProfiles = new IProfile[4];
        Stack<IProfile> unusedProfiles = new Stack<>();

        // try to keep existing active profiles in the same positions
        for (int i = 0; i < mProfiles.size(); i++) {
            IProfile p = mProfiles.get(i);
            if (p.isSelectable()) {
                boolean used = false;
                for (int j = 0; j < 4; j++) {
                    if (previousActiveProfiles[j] == p) {
                        newActiveProfiles[j] = p;
                        used = true;
                        break;
                    }
                }
                if (!used) {
                    unusedProfiles.push(p);
                }
            }
        }

        Stack<IProfile> activeProfiles = new Stack<>();
        // try to fill the gaps with new available profiles
        for (int i = 0; i < 4; i++) {
            if (newActiveProfiles[i] != null) {
                activeProfiles.push(newActiveProfiles[i]);
            } else if (!unusedProfiles.isEmpty()) {
                activeProfiles.push(unusedProfiles.pop());
            }
        }

        Stack<IProfile> reversedActiveProfiles = new Stack<>();
        while (!activeProfiles.empty()) {
            reversedActiveProfiles.push(activeProfiles.pop());
        }

        // reassign active profiles
        if (reversedActiveProfiles.isEmpty()) {
            mCurrentProfile = null;
        } else {
            mCurrentProfile = reversedActiveProfiles.pop();
        }
        if (reversedActiveProfiles.isEmpty()) {
            mProfileFirst = null;
        } else {
            mProfileFirst = reversedActiveProfiles.pop();
        }
        if (reversedActiveProfiles.isEmpty()) {
            mProfileSecond = null;
        } else {
            mProfileSecond = reversedActiveProfiles.pop();
        }
        if (reversedActiveProfiles.isEmpty()) {
            mProfileThird = null;
        } else {
            mProfileThird = reversedActiveProfiles.pop();
        }
    }

    /**
     * helper method to switch the profiles
     *
     * @param newSelection
     * @return true if the new selection was the current profile
     */
    protected boolean switchProfiles(IProfile newSelection) {
        if (newSelection == null) {
            return false;
        }
        if (mCurrentProfile == newSelection) {
            return true;
        }

        if (mAlternativeProfileHeaderSwitching) {
            int prevSelection = -1;
            if (mProfileFirst == newSelection) {
                prevSelection = 1;
            } else if (mProfileSecond == newSelection) {
                prevSelection = 2;
            } else if (mProfileThird == newSelection) {
                prevSelection = 3;
            }

            IProfile tmp = mCurrentProfile;
            mCurrentProfile = newSelection;

            if (prevSelection == 1) {
                mProfileFirst = tmp;
            } else if (prevSelection == 2) {
                mProfileSecond = tmp;
            } else if (prevSelection == 3) {
                mProfileThird = tmp;
            }
        } else {
            if (mProfiles != null) {
                ArrayList<IProfile> previousActiveProfiles = new ArrayList<>(Arrays.asList(mCurrentProfile, mProfileFirst, mProfileSecond, mProfileThird));

                if (previousActiveProfiles.contains(newSelection)) {
                    int position = -1;

                    for (int i = 0; i < 4; i++) {
                        if (previousActiveProfiles.get(i) == newSelection) {
                            position = i;
                            break;
                        }
                    }

                    if (position != -1) {
                        previousActiveProfiles.remove(position);
                        previousActiveProfiles.add(0, newSelection);

                        mCurrentProfile = previousActiveProfiles.get(0);
                        mProfileFirst = previousActiveProfiles.get(1);
                        mProfileSecond = previousActiveProfiles.get(2);
                        mProfileThird = previousActiveProfiles.get(3);
                    }
                } else {
                    mProfileThird = mProfileSecond;
                    mProfileSecond = mProfileFirst;
                    mProfileFirst = mCurrentProfile;
                    mCurrentProfile = newSelection;
                }
            }
        }

        //if we only show the small profile images we have to make sure the first (would be the current selected) profile is also shown
        if (mOnlySmallProfileImagesVisible) {
            mProfileThird = mProfileSecond;
            mProfileSecond = mProfileFirst;
            mProfileFirst = mCurrentProfile;
            //mCurrentProfile = mProfileThird;
        }

        buildProfiles();

        return false;
    }

    /**
     * helper method to build the views for the ui
     */
    protected void buildProfiles() {
        mCurrentProfileView.setVisibility(View.GONE);
        mAccountSwitcherArrow.setVisibility(View.GONE);
        mProfileFirstView.setVisibility(View.GONE);
        mProfileFirstView.setOnClickListener(null);
        mProfileSecondView.setVisibility(View.GONE);
        mProfileSecondView.setOnClickListener(null);
        mProfileThirdView.setVisibility(View.GONE);
        mProfileThirdView.setOnClickListener(null);
        mCurrentProfileName.setText("");
        mCurrentProfileEmail.setText("");

        handleSelectionView(mCurrentProfile, true);

        if (mCurrentProfile != null) {
            if ((mProfileImagesVisible || mOnlyMainProfileImageVisible) && !mOnlySmallProfileImagesVisible) {
                setImageOrPlaceholder(mCurrentProfileView, mCurrentProfile.getIcon());
                if (mProfileImagesClickable) {
                    mCurrentProfileView.setOnClickListener(onCurrentProfileClickListener);
                    mCurrentProfileView.setOnLongClickListener(onCurrentProfileLongClickListener);
                    mCurrentProfileView.disableTouchFeedback(false);
                } else {
                    mCurrentProfileView.disableTouchFeedback(true);
                }
                mCurrentProfileView.setVisibility(View.VISIBLE);

                mCurrentProfileView.invalidate();
            } else if (mCompactStyle) {
                mCurrentProfileView.setVisibility(View.GONE);
            }

            handleSelectionView(mCurrentProfile, true);
            mAccountSwitcherArrow.setVisibility(View.VISIBLE);
            mCurrentProfileView.setTag(R.id.material_drawer_profile_header, mCurrentProfile);

            StringHolder.applyTo(mCurrentProfile.getName(), mCurrentProfileName);
            StringHolder.applyTo(mCurrentProfile.getEmail(), mCurrentProfileEmail);

            if (mProfileFirst != null && mProfileImagesVisible && !mOnlyMainProfileImageVisible) {
                setImageOrPlaceholder(mProfileFirstView, mProfileFirst.getIcon());
                mProfileFirstView.setTag(R.id.material_drawer_profile_header, mProfileFirst);
                if (mProfileImagesClickable) {
                    mProfileFirstView.setOnClickListener(onProfileClickListener);
                    mProfileFirstView.setOnLongClickListener(onProfileLongClickListener);
                    mProfileFirstView.disableTouchFeedback(false);
                } else {
                    mProfileFirstView.disableTouchFeedback(true);
                }
                mProfileFirstView.setVisibility(View.VISIBLE);
                mProfileFirstView.invalidate();
            }
            if (mProfileSecond != null && mProfileImagesVisible && !mOnlyMainProfileImageVisible) {
                setImageOrPlaceholder(mProfileSecondView, mProfileSecond.getIcon());
                mProfileSecondView.setTag(R.id.material_drawer_profile_header, mProfileSecond);
                if (mProfileImagesClickable) {
                    mProfileSecondView.setOnClickListener(onProfileClickListener);
                    mProfileSecondView.setOnLongClickListener(onProfileLongClickListener);
                    mProfileSecondView.disableTouchFeedback(false);
                } else {
                    mProfileSecondView.disableTouchFeedback(true);
                }
                mProfileSecondView.setVisibility(View.VISIBLE);
                mProfileSecondView.invalidate();
            }
            if (mProfileThird != null && mThreeSmallProfileImages && mProfileImagesVisible && !mOnlyMainProfileImageVisible) {
                setImageOrPlaceholder(mProfileThirdView, mProfileThird.getIcon());
                mProfileThirdView.setTag(R.id.material_drawer_profile_header, mProfileThird);
                if (mProfileImagesClickable) {
                    mProfileThirdView.setOnClickListener(onProfileClickListener);
                    mProfileThirdView.setOnLongClickListener(onProfileLongClickListener);
                    mProfileThirdView.disableTouchFeedback(false);
                } else {
                    mProfileThirdView.disableTouchFeedback(true);
                }
                mProfileThirdView.setVisibility(View.VISIBLE);
                mProfileThirdView.invalidate();
            }
        } else if (mProfiles != null && mProfiles.size() > 0) {
            IProfile profile = mProfiles.get(0);
            mAccountHeader.setTag(R.id.material_drawer_profile_header, profile);
            handleSelectionView(mCurrentProfile, true);
            mAccountSwitcherArrow.setVisibility(View.VISIBLE);
            if (mCurrentProfile != null) {
                StringHolder.applyTo(mCurrentProfile.getName(), mCurrentProfileName);
                StringHolder.applyTo(mCurrentProfile.getEmail(), mCurrentProfileEmail);
            }
        }

        if (!mSelectionFirstLineShown) {
            mCurrentProfileName.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(mSelectionFirstLine)) {
            mCurrentProfileName.setText(mSelectionFirstLine);
        }
        if (!mSelectionSecondLineShown) {
            mCurrentProfileEmail.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(mSelectionSecondLine)) {
            mCurrentProfileEmail.setText(mSelectionSecondLine);
        }

        //if we disabled the list
        if (!mSelectionListEnabled || !mSelectionListEnabledForSingleProfile && mProfileFirst == null && (mProfiles == null || mProfiles.size() == 1)) {
            mAccountSwitcherArrow.setVisibility(View.GONE);
            handleSelectionView(null, false);
        }

        //if we disabled the list but still have set a custom listener
        if (mOnAccountHeaderSelectionViewClickListener != null) {
            handleSelectionView(mCurrentProfile, true);
        }
    }

    /**
     * small helper method to set an profile image or a placeholder
     *
     * @param iv
     * @param imageHolder
     */
    private void setImageOrPlaceholder(ImageView iv, ImageHolder imageHolder) {
        //cancel previous started image loading processes
        DrawerImageLoader.getInstance().cancelImage(iv);
        //set the placeholder
        iv.setImageDrawable(DrawerImageLoader.getInstance().getImageLoader().placeholder(iv.getContext(), DrawerImageLoader.Tags.PROFILE.name()));
        //set the real image (probably also the uri)
        ImageHolder.applyTo(imageHolder, iv, DrawerImageLoader.Tags.PROFILE.name());
    }

    /**
     * onProfileClickListener to notify onClick on the current profile image
     */
    private View.OnClickListener onCurrentProfileClickListener = new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            onProfileImageClick(v, true);
        }
    };

    /**
     * onProfileClickListener to notify onClick on a profile image
     */
    private View.OnClickListener onProfileClickListener = new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            onProfileImageClick(v, false);
        }
    };

    /**
     * calls the mOnAccountHEaderProfileImageListener and continues with the actions afterwards
     *
     * @param v
     * @param current
     */
    private void onProfileImageClick(View v, boolean current) {
        IProfile profile = (IProfile) v.getTag(R.id.material_drawer_profile_header);

        boolean consumed = false;
        if (mOnAccountHeaderProfileImageListener != null) {
            consumed = mOnAccountHeaderProfileImageListener.onProfileImageClick(v, profile, current);
        }

        //if the event was already consumed by the click don't continue. note that this will also stop the profile change event
        if (!consumed) {
            onProfileClick(v, current);
        }
    }

    /**
     * onProfileLongClickListener to call the onProfileImageLongClick on the current profile image
     */
    private View.OnLongClickListener onCurrentProfileLongClickListener = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mOnAccountHeaderProfileImageListener != null) {
                IProfile profile = (IProfile) v.getTag(R.id.material_drawer_profile_header);
                return mOnAccountHeaderProfileImageListener.onProfileImageLongClick(v, profile, true);
            }
            return false;
        }
    };

    /**
     * onProfileLongClickListener to call the onProfileImageLongClick on a profile image
     */
    private View.OnLongClickListener onProfileLongClickListener = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mOnAccountHeaderProfileImageListener != null) {
                IProfile profile = (IProfile) v.getTag(R.id.material_drawer_profile_header);
                return mOnAccountHeaderProfileImageListener.onProfileImageLongClick(v, profile, false);
            }
            return false;
        }
    };

    protected void onProfileClick(View v, boolean current) {
        final IProfile profile = (IProfile) v.getTag(R.id.material_drawer_profile_header);
        switchProfiles(profile);

        //reset the drawer content
        resetDrawerContent(v.getContext());

        //notify the MiniDrawer about the clicked profile (only if one exists and is hooked to the Drawer
        if (mDrawer != null && mDrawer.getDrawerBuilder() != null && mDrawer.getDrawerBuilder().mMiniDrawer != null) {
            mDrawer.getDrawerBuilder().mMiniDrawer.onProfileClick();
        }

        //notify about the changed profile
        boolean consumed = false;
        if (mOnAccountHeaderListener != null) {
            consumed = mOnAccountHeaderListener.onProfileChanged(v, profile, current);
        }

        if (!consumed) {
            if (mOnProfileClickDrawerCloseDelay > 0) {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (mDrawer != null) {
                            mDrawer.closeDrawer();
                        }
                    }
                }, mOnProfileClickDrawerCloseDelay);
            } else {
                if (mDrawer != null) {
                    mDrawer.closeDrawer();
                }
            }
        }
    }

    /**
     * get the current selection
     *
     * @return
     */
    protected int getCurrentSelection() {
        if (mCurrentProfile != null && mProfiles != null) {
            int i = 0;
            for (IProfile profile : mProfiles) {
                if (profile == mCurrentProfile) {
                    return i;
                }
                i++;
            }
        }
        return -1;
    }

    /**
     * onSelectionClickListener to notify the onClick on the checkbox
     */
    private View.OnClickListener onSelectionClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean consumed = false;
            if (mOnAccountHeaderSelectionViewClickListener != null) {
                consumed = mOnAccountHeaderSelectionViewClickListener.onClick(v, (IProfile) v.getTag(R.id.material_drawer_profile_header));
            }

            if (mAccountSwitcherArrow.getVisibility() == View.VISIBLE && !consumed) {
                toggleSelectionList(v.getContext());
            }
        }
    };

    /**
     * helper method to toggle the collection
     *
     * @param ctx
     */
    protected void toggleSelectionList(Context ctx) {
        if (mDrawer != null) {
            //if we already show the list. reset everything instead
            if (mDrawer.switchedDrawerContent()) {
                resetDrawerContent(ctx);
                mSelectionListShown = false;
            } else {
                //build and set the drawer selection list
                buildDrawerSelectionList();

                // update the arrow image within the drawer
                mAccountSwitcherArrow.clearAnimation();
                ViewCompat.animate(mAccountSwitcherArrow).rotation(180).start();
                //mAccountSwitcherArrow.setImageDrawable(new IconicsDrawable(ctx, MaterialDrawerFont.Icon.mdf_arrow_drop_up).sizeRes(R.dimen.material_drawer_account_header_dropdown).paddingRes(R.dimen.material_drawer_account_header_dropdown_padding).color(ColorHolder.color(mTextColor, ctx, R.attr.material_drawer_header_selection_text, R.color.material_drawer_header_selection_text)));
                mSelectionListShown = true;
            }
        }
    }

    /**
     * helper method to build and set the drawer selection list
     */
    protected void buildDrawerSelectionList() {
        int selectedPosition = -1;
        int position = 0;
        ArrayList<IDrawerItem> profileDrawerItems = new ArrayList<>();
        if (mProfiles != null) {
            for (IProfile profile : mProfiles) {
                if (profile == mCurrentProfile) {
                    if (mCurrentHiddenInList) {
                        continue;
                    } else {
                        selectedPosition = mDrawer.mDrawerBuilder.getItemAdapter().getGlobalPosition(position);
                    }
                }
                if (profile instanceof IDrawerItem) {
                    ((IDrawerItem) profile).withSetSelected(false);
                    profileDrawerItems.add((IDrawerItem) profile);
                }
                position = position + 1;
            }
        }
        mDrawer.switchDrawerContent(onDrawerItemClickListener, onDrawerItemLongClickListener, profileDrawerItems, selectedPosition);
    }

    /**
     * onDrawerItemClickListener to catch the selection for the new profile!
     */
    private Drawer.OnDrawerItemClickListener onDrawerItemClickListener = new Drawer.OnDrawerItemClickListener() {
        @Override
        public boolean onItemClick(final View view, int position, final IDrawerItem drawerItem) {
            final boolean isCurrentSelectedProfile;
            if (drawerItem != null && drawerItem instanceof IProfile && drawerItem.isSelectable()) {
                isCurrentSelectedProfile = switchProfiles((IProfile) drawerItem);
            } else {
                isCurrentSelectedProfile = false;
            }

            if (mResetDrawerOnProfileListClick) {
                mDrawer.setOnDrawerItemClickListener(null);
            }

            //wrap the onSelection call and the reset stuff within a handler to prevent lag
            if (mResetDrawerOnProfileListClick && mDrawer != null && view != null && view.getContext() != null) {
                resetDrawerContent(view.getContext());
            }

            //notify the MiniDrawer about the clicked profile (only if one exists and is hooked to the Drawer
            if (mDrawer != null && mDrawer.getDrawerBuilder() != null && mDrawer.getDrawerBuilder().mMiniDrawer != null) {
                mDrawer.getDrawerBuilder().mMiniDrawer.onProfileClick();
            }

            boolean consumed = false;
            if (drawerItem != null && drawerItem instanceof IProfile) {
                if (mOnAccountHeaderListener != null) {
                    consumed = mOnAccountHeaderListener.onProfileChanged(view, (IProfile) drawerItem, isCurrentSelectedProfile);
                }
            }

            //if a custom behavior was chosen via the CloseDrawerOnProfileListClick then use this. else react on the result of the onProfileChanged listener
            if (mCloseDrawerOnProfileListClick != null) {
                consumed = consumed && !mCloseDrawerOnProfileListClick;
            }

            //totally custom handling of the drawer behavior as otherwise the selection of the profile list is set to the Drawer
            if (mDrawer != null && !consumed) {
                //close the drawer after click
                mDrawer.mDrawerBuilder.closeDrawerDelayed();
            }

            //consume the event to prevent setting the clicked item as selected in the already switched item list
            return true;
        }
    };

    /**
     * onDrawerItemLongClickListener to catch the longClick for a profile
     */
    private Drawer.OnDrawerItemLongClickListener onDrawerItemLongClickListener = new Drawer.OnDrawerItemLongClickListener() {
        @Override
        public boolean onItemLongClick(View view, int position, IDrawerItem drawerItem) {
            //if a longClickListener was defined use it
            if (mOnAccountHeaderItemLongClickListener != null) {
                final boolean isCurrentSelectedProfile;
                isCurrentSelectedProfile = drawerItem != null && drawerItem.isSelected();

                if (drawerItem != null && drawerItem instanceof IProfile) {
                    return mOnAccountHeaderItemLongClickListener.onProfileLongClick(view, (IProfile) drawerItem, isCurrentSelectedProfile);
                }
            }
            return false;
        }
    };

    /**
     * helper method to reset the drawer content
     */
    private void resetDrawerContent(Context ctx) {
        if (mDrawer != null) {
            mDrawer.resetDrawerContent();
        }

        mAccountSwitcherArrow.clearAnimation();
        ViewCompat.animate(mAccountSwitcherArrow).rotation(0).start();
        //mAccountSwitcherArrow.setImageDrawable(new IconicsDrawable(ctx, MaterialDrawerFont.Icon.mdf_arrow_drop_down).sizeRes(R.dimen.material_drawer_account_header_dropdown).paddingRes(R.dimen.material_drawer_account_header_dropdown_padding).color(ColorHolder.color(mTextColor, ctx, R.attr.material_drawer_header_selection_text, R.color.material_drawer_header_selection_text)));
    }

    /**
     * small helper class to update the header and the list
     */
    protected void updateHeaderAndList() {
        //recalculate the profiles
        calculateProfiles();
        //update the profiles in the header
        buildProfiles();
        //if we currently show the list add the new item directly to it
        if (mSelectionListShown) {
            buildDrawerSelectionList();
        }
    }
}
