package org.hso.texturesyncclient.controller import javafx.application.Platform import javafx.collections.ObservableList import javafx.event.EventHandler import javafx.stage.DirectoryChooser import org.hso.texturesyncclient.alerts.JFXOkayCancelAlert import org.hso.texturesyncclient.controller.net.AutoConnect import org.hso.texturesyncclient.controller.net.Connection import org.hso.texturesyncclient.model.GUIModel import org.hso.texturesyncclient.model.Sha256 import org.hso.texturesyncclient.model.Texture import org.hso.texturesyncclient.model.TextureFormat import org.hso.texturesyncclient.view.importView.ImportView import org.hso.texturesyncclient.view.importView.ImportViewController import org.hso.texturesyncclient.view.mainView.MainView import org.hso.texturesyncclient.view.mainView.MainViewController import org.hso.texturesyncclient.view.startupView.StartupView import org.hso.texturesyncclient.view.startupView.StartupViewController import tornadofx.Controller import tornadofx.observable import java.net.InetAddress import java.util.Calendar import java.io.File import javax.imageio.ImageIO import java.util.UUID import java.nio.file.Files import java.io.FileOutputStream import java.text.SimpleDateFormat import java.text.DateFormat class RootController : Controller() { private val mvc: MainViewController by inject() private val svc: StartupViewController by inject() private val ivc: ImportViewController by inject() private lateinit var con: Connection private lateinit var selectedTexture: Texture private var lastExportDir: String = System.getProperty("user.home") /** * calculate the resolution, get today's date -> upload to server * @param path the absolute path of the file on the client's system * @param name the file name * @param tags all tags for the file */ fun importTexture(path: String, name: String, tags: ObservableList) { val data = Files.readAllBytes(File(path).toPath()) // this is the image as byte array val uuid = UUID.randomUUID() val format = if (File(path).extension.toLowerCase() == "png") TextureFormat.PNG else TextureFormat.JPEG val bimg = ImageIO.read(File(path)) //image for obtaining resolution val resolution = Pair(bimg.height, bimg.width) val cal = Calendar.getInstance() //calendar obj with current time val hash = Sha256(data) //Todo free image val newTexture = Texture(uuid, name, tags.toTypedArray(), format, resolution, cal, hash) try { con.uploadTexture(newTexture, data) println("Texture upload successful") } catch (e: Exception) { println(e) } } /** * Initialize connection to server and switch to MainView if connected * @param name server name as IP or domain */ fun initConnection(name: String) { if (name == " ") { //no user input, try automatic connect or restore address from settings file println("try auto connect") try { val foundServer = AutoConnect.searchServer() if (foundServer != null) { println("[auto] server found") con = foundServer con.ping() println("auto Connection to Server successful") switchStartupToMain() } else { println("[auto] no server found") } } catch (e: Exception) { println(e) println("auto Connection to Server NOT successful") } if (SettingsController.serverAddressIsSet()) { println("[file] try connect with settings file") try { svc.setServerAddress(SettingsController.getServerAddress()) con = Connection(InetAddress.getByName(SettingsController.getServerAddress())) con.ping() println("[file] Connection to Server successful") switchStartupToMain() } catch (e: Exception) { println(e) println("[file] Connection to Server NOT successful") } } else { println("[file] no address in settings file") } } else { //try to connect with user input try { println("try connect with user input") con = Connection(InetAddress.getByName(name)) con.ping() println("Connection to Server successful") SettingsController.setServerAddress(name) //store address in settings file switchStartupToMain() println("swithing to MainView @ initCon") } catch (e: Exception) { println(e) println("Connection to Server NOT successful") } } } fun queryElements(tags: ObservableList): ArrayList { val previewList = arrayListOf() try { con.query(tags.toTypedArray()).forEach { runAsync { Platform.runLater { mvc.addElement(GUIModel(it, con.getTexturePreview(it.textureHash))) } } } } catch (e: Exception) { println(e) } println(previewList.size) return previewList } // TODO this could be a companion object fun switchStartupToMain() { Platform.runLater { find(StartupView::class).replaceWith(MainView::class, sizeToScene = true, centerOnScreen = true) } } // These runLater calls should be unnecessary fun switchMainToImport() { Platform.runLater { find(MainView::class).replaceWith(ImportView::class, sizeToScene = true, centerOnScreen = true) } } fun switchImportToMain() { Platform.runLater { find(ImportView::class).replaceWith(MainView::class, sizeToScene = true, centerOnScreen = true) } } /** * save the texture file to a local directory * @param data the texture as meta element */ fun exportTexture(data: Texture) { val directoryChooser = DirectoryChooser() directoryChooser.title = "Export Verzeichnis wählen" directoryChooser.initialDirectory = File(lastExportDir) val dir = directoryChooser.showDialog(primaryStage) if (dir != null) { val extension = if (data.format == TextureFormat.PNG) ".png" else ".jpeg" //get file format val filePath = "$dir/${data.name}$extension" //build absolute exported texture path val exportedFile = File(filePath) //create file val fileout = FileOutputStream(exportedFile) fileout.write(con.getTextureFile(data.textureHash)) //write bytes in file fileout.close() lastExportDir = dir.absolutePath //store last user chosen dir } } /** * show the detailed meta information in the DetailView * @param data the texture as meta element */ fun showDetail(data: Texture) { mvc.setPreview3DTexture(con.getTexturePreview(data.textureHash)) val sdf = SimpleDateFormat("dd.MM.yyyy") mvc.setMeta(data.name, "${data.resolution.first.toString()}px x ${data.resolution.second.toString()}px", data.format.toString(), sdf.format(data.addedOn.time)) mvc.setTags(data.tags.toList().observable()) selectedTexture = data } /** * remove a texture from the FolderView and the server * @param data the texture as meta element */ fun deleteTexture(data: Texture) { val dialogDelete = JFXOkayCancelAlert( "Löschen", "Textur wirklich löschen?", "-fx-button-type: RAISED; -fx-background-color: #2b7bbb; -fx-text-fill: #000000;" ) dialogDelete.okayAction = EventHandler { mvc.removeTextureFromView(data) con.deleteTexture(data) } dialogDelete.cancelAction = EventHandler { // Do nothing } dialogDelete.showAndWait() } fun updateTexture(chips: ObservableList) { val uuid = UUID.randomUUID() val newTexture = Texture( uuid, selectedTexture.name, chips.toTypedArray(), selectedTexture.format, selectedTexture.resolution, selectedTexture.addedOn, selectedTexture.textureHash ) con.updateTexture(selectedTexture, newTexture, con.getTextureFile(selectedTexture.textureHash)) } }