package com.scrivenvar;
import com.scrivenvar.preferences.FilePreferencesFactory;
import com.scrivenvar.service.Options;
import com.scrivenvar.service.Snitch;
import com.scrivenvar.service.events.Notifier;
import com.scrivenvar.util.ResourceWalker;
import com.scrivenvar.util.StageState;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import java.awt.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Map;
import java.util.logging.LogManager;
import static com.scrivenvar.Constants.*;
import static com.scrivenvar.Messages.get;
import static java.awt.font.TextAttribute.LIGATURES;
import static java.awt.font.TextAttribute.LIGATURES_ON;
import static javafx.scene.input.KeyCode.F11;
import static javafx.scene.input.KeyEvent.KEY_PRESSED;
public final class Main extends Application {
static {
LogManager.getLogManager().reset();
System.err.close();
}
private final static Notifier sNotifier = Services.load( Notifier.class );
private final Options mOptions = Services.load( Options.class );
private final Snitch mSnitch = Services.load( Snitch.class );
private final Thread mSnitchThread = new Thread( getSnitch() );
private final MainWindow mMainWindow = new MainWindow();
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private StageState mStageState;
public static void main( final String[] args ) {
initPreferences();
initFonts();
launch( args );
}
@Override
public void start( final Stage stage ) {
initState( stage );
initStage( stage );
initSnitch();
stage.show();
getMainWindow().init();
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static void initFonts() {
final var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
ResourceWalker.walk(
FONT_DIRECTORY, path -> {
final var uri = path.toUri();
final var filename = path.toString();
try( final var is = openFont( uri, filename ) ) {
final var font = Font.createFont( Font.TRUETYPE_FONT, is );
final Map attributes = font.getAttributes();
attributes.put( LIGATURES, LIGATURES_ON );
ge.registerFont( font.deriveFont( attributes ) );
} catch( final Exception e ) {
getNotifier().notify( e );
}
}
);
} catch( final Exception e ) {
getNotifier().notify( e );
}
}
private static InputStream openFont( final URI uri, final String filename )
throws IOException {
return uri.getScheme().equals( "jar" )
? Main.class.getResourceAsStream( filename )
: new FileInputStream( filename );
}
private static void initPreferences() {
System.setProperty(
"java.util.prefs.PreferencesFactory",
FilePreferencesFactory.class.getName()
);
}
private void initState( final Stage stage ) {
mStageState = new StageState( stage, getOptions().getState() );
}
private void initStage( final Stage stage ) {
stage.getIcons().addAll(
createImage( FILE_LOGO_16 ),
createImage( FILE_LOGO_32 ),
createImage( FILE_LOGO_128 ),
createImage( FILE_LOGO_256 ),
createImage( FILE_LOGO_512 ) );
stage.setTitle( getApplicationTitle() );
stage.setScene( getScene() );
stage.addEventHandler( KEY_PRESSED, event -> {
if( F11.equals( event.getCode() ) ) {
stage.setFullScreen( !stage.isFullScreen() );
}
} );
}
private void initSnitch() {
getSnitchThread().start();
}
@Override
public void stop() throws InterruptedException {
getSnitch().stop();
final Thread thread = getSnitchThread();
thread.interrupt();
thread.join();
}
private static Notifier getNotifier() {
return sNotifier;
}
private Snitch getSnitch() {
return mSnitch;
}
private Thread getSnitchThread() {
return mSnitchThread;
}
private Options getOptions() {
return mOptions;
}
private MainWindow getMainWindow() {
return mMainWindow;
}
private Scene getScene() {
return getMainWindow().getScene();
}
private String getApplicationTitle() {
return get( "Main.title" );
}
private Image createImage( final String filename ) {
return new Image( filename );
}
}