package reading.component.index import rx._ import scalatags.JsDom.all._ import scalacss.Defaults._ import scalacss.ScalatagsCss._ import reading.component.index.style.{ Menu => MenuStyle } import reading.models._ import reading.utils.RxUtils._ object Menu { def apply( books: Rx[Seq[Book]], filters: Var[Seq[Filter]], search: Var[String], showFiltersMenu: Var[Boolean] )( implicit ctx: Ctx.Owner ): Frag = div( MenuStyle.render, Rx(if (showFiltersMenu()) MenuStyle.show else MenuStyle.empty), MenuStyle.menu, div(MenuStyle.background), div( MenuStyle.content, Rx(header(showFiltersMenu, filters().length)), div( MenuStyle.groups, Rx { filters().find(_.kind == FilterKind.Grade) match { case Some(grade) => val programs = Program.values.filter(p => Program.grade(p).toString() == grade.nonFormattedName) group(books, filters, search, grade.name, programs.map(Filter.apply(_)), Some(grade)) case None => group(books, filters, search, "Classe", Grade.values.map(Filter.apply(_))) } }, Rx { filters().find(_.kind == FilterKind.GroupedTheme) match { case Some(groupedTheme) => val themes = Theme.values.filter(t => Theme.groupedTheme(t).toString() == groupedTheme.nonFormattedName) group(books, filters, search, groupedTheme.name, themes.map(Filter.apply(_)), Some(groupedTheme)) case None => group(books, filters, search, "Theme", GroupedTheme.values.map(Filter.apply(_))) } }, group(books, filters, search, "Genre", Genre.values.sorted.map(Filter.apply(_))), group(books, filters, search, "Niveau", Level.values.map(Filter.apply(_))), group(books, filters, search, "PĂ©riode", Period.values.map(Filter.apply(_))) ), footer(books, filters, search, showFiltersMenu) ) ) def header(showFiltersMenu: Var[Boolean], count: Int): Frag = div( MenuStyle.header, "Filtrer", if (count > 0) span(MenuStyle.filtersCount, count) else span("") ) def group( books: Rx[Seq[Book]], filters: Var[Seq[Filter]], search: Var[String], name: String, groupFilters: Seq[Filter], parentFilter: Option[Filter] = None )( implicit ctx: Ctx.Owner ): Frag = { val filtersWithCount = Rx { groupFilters .map(filter => (filter, Filter.add(books(), filter).length)) .filter(_._2 > 0) } Rx { if (filtersWithCount().isEmpty) span("") else div( div( MenuStyle.filterTitle, parentFilter.map { filter => onclick := (() => FilterUtils.remove(filters, search, filter)) }.getOrElse(""), if (parentFilter.isDefined) MenuStyle.activeFilter else "", name, Rx { val count = filters().filter(f => groupFilters.exists(f == _)).length if (count > 0) span(MenuStyle.filterTitleCount, count) else span("") } ), div( filtersWithCount().map { case (filter, count) => { val isActive = Filter.contains(filters(), filter) button( MenuStyle.filter, if (isActive) MenuStyle.activeFilter else "", onclick := (() => if (isActive) FilterUtils.remove(filters, search, filter) else FilterUtils.add(filters, search, filter)), span( span(filter.name.capitalize), span(MenuStyle.filterCount, count) ) ) } } ) ) } } def footer( books: Rx[Seq[Book]], filters: Var[Seq[Filter]], search: Var[String], showFiltersMenu: Var[Boolean] )( implicit ctx: Ctx.Owner ): Frag = div( MenuStyle.footer, div( MenuStyle.clear, onclick := (() => FilterUtils.removeAll(filters, search)), "Effacer" ), div( MenuStyle.returnToBooks, onclick := (() => showFiltersMenu() = false), "Afficher", Rx { span(MenuStyle.bookCount, books().length) } ) ) }