<commit_before>/*
 * UniTime 3.2 (University Timetabling Application)
 * Copyright (C) 2010, UniTime LLC, and individual contributors
 * as indicated by the @authors tag.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
*/
package org.unitime.timetable.gwt.client.page;

import java.util.List;

import org.unitime.timetable.gwt.client.Client;
import org.unitime.timetable.gwt.client.Pages;
import org.unitime.timetable.gwt.client.ToolBox;
import org.unitime.timetable.gwt.client.Client.GwtPageChangeEvent;
import org.unitime.timetable.gwt.client.Client.GwtPageChangedHandler;
import org.unitime.timetable.gwt.client.widgets.LoadingWidget;
import org.unitime.timetable.gwt.client.widgets.UniTimeFrameDialog;
import org.unitime.timetable.gwt.services.MenuService;
import org.unitime.timetable.gwt.services.MenuServiceAsync;
import org.unitime.timetable.gwt.shared.MenuInterface;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ScrollEvent;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.MenuItemSeparator;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;

/**
 * @author <NAME>
 */
public class UniTimeMenuBar extends Composite {
	protected final MenuServiceAsync iService = GWT.create(MenuService.class);
	
	private MenuBar iMenu;
	private SimplePanel iSimple = null;
	
	private int iLastScrollLeft = 0, iLastScrollTop = 0, iLastClientWidth = 0;
	private Timer iMoveTimer;
	
	public UniTimeMenuBar(boolean absolute) {
		iMenu = new MenuBar();
		iMenu.addStyleName("unitime-NoPrint");
		iMenu.addStyleName("unitime-Menu");
		initWidget(iMenu);
		
		if (absolute) {
			iMenu.getElement().getStyle().setPosition(Position.ABSOLUTE);
			move(false);
			iMoveTimer = new Timer() {
				@Override
				public void run() {
					move(true);
				}
			};
			Window.addResizeHandler(new ResizeHandler() {
				@Override
				public void onResize(ResizeEvent event) {
					delayedMove();
				}
			});
			Window.addWindowScrollHandler(new Window.ScrollHandler() {
				@Override
				public void onWindowScroll(ScrollEvent event) {
					delayedMove();
				}
			});
			Client.addGwtPageChangedHandler(new GwtPageChangedHandler() {
				@Override
				public void onChange(GwtPageChangeEvent event) {
					delayedMove();
				}
			});
			iSimple = new SimplePanel();
			iSimple.getElement().getStyle().setHeight(23, Unit.PX);
			new Timer() {
				@Override
				public void run() {
					delayedMove();
				}
			}.scheduleRepeating(5000);
		}
		
	}
	
	private void attach(final RootPanel rootPanel) {
		iService.getMenu(new AsyncCallback<List<MenuInterface>>() {
			@Override
			public void onSuccess(List<MenuInterface> result) {
				initMenu(iMenu, result, 0);
				if (iSimple != null)
					rootPanel.add(iSimple);
				rootPanel.add(UniTimeMenuBar.this);
				if (iSimple != null)
					iSimple.setHeight(iMenu.getOffsetHeight() + "px");
			}
			@Override
			public void onFailure(Throwable caught) {
			}
		});
	}
	
	private void move(boolean show) {
		iLastClientWidth = Window.getClientWidth();
		iLastScrollLeft = Window.getScrollLeft();
		iLastScrollTop = Window.getScrollTop();
		iMenu.getElement().getStyle().setWidth(iLastClientWidth - 2, Unit.PX);
		iMenu.getElement().getStyle().setLeft(iLastScrollLeft, Unit.PX);
		iMenu.getElement().getStyle().setTop(iLastScrollTop, Unit.PX);
		iMenu.setVisible(true);
	}
	
	private boolean needsMove() {
		return iLastClientWidth != Window.getClientWidth() ||
			iLastScrollLeft != Window.getScrollLeft() || iLastScrollTop != Window.getScrollTop();
	}
	
	private void delayedMove() {
		if (needsMove()) {
			iMenu.setVisible(false);
			iMoveTimer.schedule(100);
		}
	}
	
	private void initMenu(MenuBar menu, List<MenuInterface> items, int level) {
		final MenuInterface.ValueEncoder encoder = new MenuInterface.ValueEncoder() {
			@Override
			public String encode(String value) {
				return URL.encodeQueryString(value);
			}
		};
		MenuItemSeparator lastSeparator = null;
		for (final MenuInterface item: items) {
			if (item.isSeparator()) {
				lastSeparator = new MenuItemSeparator();
				menu.addSeparator(lastSeparator);
			} else if (item.hasSubMenus()) {
				MenuBar m = new MenuBar(true);
				initMenu(m, item.getSubMenus(), level + 1);
				menu.addItem(new MenuItem(item.getName().replace(" ", "&nbsp;"), true, m));
			} else {
				menu.addItem(new MenuItem(item.getName().replace(" ", "&nbsp;"), true, new Command() {
					@Override
					public void execute() {
						if (item.hasPage())
							openUrl(item.getName(), item.getURL(encoder), item.getTarget());
					}
				}));
			}
		}
		if (level == 0 && lastSeparator != null) {
			lastSeparator.setStyleName("unitime-BlankSeparator");
			lastSeparator.getElement().getStyle().setWidth(100, Unit.PCT);
		}
	}
	<commit_msg>UniTime Menu  - fixed an issue introduced in revision 3046<commit_after>/*
 * UniTime 3.2 (University Timetabling Application)
 * Copyright (C) 2010, UniTime LLC, and individual contributors
 * as indicated by the @authors tag.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
*/
package org.unitime.timetable.gwt.client.page;

import java.util.List;

import org.unitime.timetable.gwt.client.Client;
import org.unitime.timetable.gwt.client.Pages;
import org.unitime.timetable.gwt.client.ToolBox;
import org.unitime.timetable.gwt.client.Client.GwtPageChangeEvent;
import org.unitime.timetable.gwt.client.Client.GwtPageChangedHandler;
import org.unitime.timetable.gwt.client.widgets.LoadingWidget;
import org.unitime.timetable.gwt.client.widgets.UniTimeFrameDialog;
import org.unitime.timetable.gwt.services.MenuService;
import org.unitime.timetable.gwt.services.MenuServiceAsync;
import org.unitime.timetable.gwt.shared.MenuInterface;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ScrollEvent;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.MenuItemSeparator;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;

/**
 * @author <NAME>
 */
public class UniTimeMenuBar extends Composite {
	protected final MenuServiceAsync iService = GWT.create(MenuService.class);
	
	private MenuBar iMenu;
	private SimplePanel iSimple = null;
	
	private int iLastScrollLeft = 0, iLastScrollTop = 0, iLastClientWidth = 0;
	private Timer iMoveTimer;
	
	public UniTimeMenuBar(boolean absolute) {
		iMenu = new MenuBar();
		iMenu.addStyleName("unitime-NoPrint");
		iMenu.addStyleName("unitime-Menu");
		initWidget(iMenu);
		
		if (absolute) {
			iMenu.getElement().getStyle().setPosition(Position.ABSOLUTE);
			move(false);
			iMoveTimer = new Timer() {
				@Override
				public void run() {
					move(true);
				}
			};
			Window.addResizeHandler(new ResizeHandler() {
				@Override
				public void onResize(ResizeEvent event) {
					delayedMove();
				}
			});
			Window.addWindowScrollHandler(new Window.ScrollHandler() {
				@Override
				public void onWindowScroll(ScrollEvent event) {
					delayedMove();
				}
			});
			Client.addGwtPageChangedHandler(new GwtPageChangedHandler() {
				@Override
				public void onChange(GwtPageChangeEvent event) {
					delayedMove();
				}
			});
			iSimple = new SimplePanel();
			iSimple.getElement().getStyle().setHeight(23, Unit.PX);
			new Timer() {
				@Override
				public void run() {
					delayedMove();
				}
			}.scheduleRepeating(5000);
		}
		
	}
	
	private void attach(final RootPanel rootPanel) {
		iService.getMenu(new AsyncCallback<List<MenuInterface>>() {
			@Override
			public void onSuccess(List<MenuInterface> result) {
				initMenu(iMenu, result, 0);
				if (iSimple != null)
					rootPanel.add(iSimple);
				rootPanel.add(UniTimeMenuBar.this);
				if (iSimple != null)
					iSimple.setHeight(iMenu.getOffsetHeight() + "px");
			}
			@Override
			public void onFailure(Throwable caught) {
			}
		});
	}
	
	private void move(boolean show) {
		iLastClientWidth = Window.getClientWidth();
		iLastScrollLeft = Window.getScrollLeft();
		iLastScrollTop = Window.getScrollTop();
		iMenu.getElement().getStyle().setWidth(iLastClientWidth - 2, Unit.PX);
		iMenu.getElement().getStyle().setLeft(iLastScrollLeft, Unit.PX);
		iMenu.getElement().getStyle().setTop(iLastScrollTop, Unit.PX);
		iMenu.setVisible(true);
	}
	
	private boolean needsMove() {
		return iLastClientWidth != Window.getClientWidth() ||
			iLastScrollLeft != Window.getScrollLeft() || iLastScrollTop != Window.getScrollTop();
	}
	
	private void delayedMove() {
		if (needsMove()) {
			iMenu.setVisible(false);
			iMoveTimer.schedule(100);
		}
	}
	
	private void initMenu(MenuBar menu, List<MenuInterface> items, int level) {
		final MenuInterface.ValueEncoder encoder = new MenuInterface.ValueEncoder() {
			@Override
			public String encode(String value) {
				return URL.encodeQueryString(value);
			}
		};
		MenuItemSeparator lastSeparator = null;
		for (final MenuInterface item: items) {
			if (item.isSeparator()) {
				lastSeparator = new MenuItemSeparator();
				menu.addSeparator(lastSeparator);
			} else if (item.hasSubMenus()) {
				if (!item.hasPage()) {
					MenuBar m = new MenuBar(true);
					initMenu(m, item.getSubMenus(), level + 1);
					menu.addItem(new MenuItem(item.getName().replace(" ", "&nbsp;"), true, m));
				} else {
					menu.addItem(new MenuItem(item.getName().replace(" ", "&nbsp;"), true, new Command() {
						@Override
						public void execute() {
							if (item.hasPage())
								openUrl(item.getName(), item.getURL(encoder), item.getTarget());
						}
					}));
					initMenu(menu, item.getSubMenus(), level);
				}
			} else {
				menu.addItem(new MenuItem(item.getName().replace(" ", "&nbsp;"), true, new Command() {
					@Override
					public void execute() {
						if (item.hasPage())
							openUrl(item.getName(), item.getURL(encoder), item.getTarget());
					}
				}));
			}
		}
		if (level == 0 && lastSeparator != null) {
			lastSeparator.setStyleName("unitime-BlankSeparator");
			lastSeparator.getElement().getStyle().setWidth(100, Unit.PCT);
		}
	}
	
{'fraction_non_alphanumeric': 0.12562570644275795, 'fraction_numerical': 0.004521233650896173, 'mean_word_length': 4.110148514851486, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7250325', 'n_tokens_mistral': 4522, 'n_tokens_neox': 3917, 'n_words': 841}