package com.opticalcobra.storybear.editor; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import com.opticalcobra.storybear.main.ILevelAppearance; import com.opticalcobra.storybear.menu.LoadingPanel; import com.opticalcobra.storybear.res.FontCache; import com.opticalcobra.storybear.res.Ressources; import com.opticalcobra.storybear.db.DBConstants; import com.opticalcobra.storybear.db.Database; import com.opticalcobra.storybear.db.HighscoreResult; import com.opticalcobra.storybear.db.WordResult; import com.opticalcobra.storybear.game.Character; import com.opticalcobra.storybear.game.Collectable; import com.opticalcobra.storybear.game.IllustrationBig; import com.opticalcobra.storybear.game.IllustrationSmall; import com.opticalcobra.storybear.game.Landscape; import com.opticalcobra.storybear.game.RenderHint; import com.opticalcobra.storybear.game.Word; public class TextAnalyzer { private Font storyTextFont = FontCache.getInstance().getFont("Standard", ((float) (Ressources.STORYTEXTSIZE))); private Database db= new Database(); private LoadingPanel loadingPanel; public TextAnalyzer(LoadingPanel lp){ loadingPanel = lp; } //TODO: Methode vervollst�ndigen /** * @author Miriam */ public StoryInfo analyzeText(Story story){ StoryInfo storyInfo = new StoryInfo(); String[] words; ArrayList<ILevelAppearance> elements = new ArrayList(); int numberOfBlocks = 0; //how many blocks are needed for a word int blockPosition = 0; //block number, where a word starts in the level int stringLength = 0; //how many pixels are needed ArrayList<RenderHint> renderHint = new ArrayList(); RenderHint rh; storyInfo.setStory(story); words = story.getText().split(" "); //analyze Text //--> check if word of the story is in our db //if word in db then return type of word, e.g. collectable, character, ... //else return null loadingPanel.setMaximum(words.length); for(String word : words){ String word_short = word.replaceAll("[^a-zA-Z ����0-9]", ""); //get the length of the word in pixels stringLength = this.numberOfPixelsOfString(word); //Math.ceil rundet immer auf: 0.1 wird zu 1.0 numberOfBlocks = (int) Math.ceil((double)stringLength / (double)Ressources.RASTERSIZE); System.out.println(word); try { WordResult wr =db.queryWordType(word_short); switch (wr.getType()){ case DBConstants.WORD_OBJECT_TYPE_CHARACTER: elements.add(new Character(blockPosition,wr.getImage_id())); //Generiere random Collectables if ((int)(Math.random()*4) == 0){ elements.add(new Collectable(blockPosition,db.getRandomCollectableNumber())); } break; case DBConstants.WORD_OBJECT_TYPE_COLLECTABLE: elements.add(new Collectable(blockPosition,wr.getImage_id())); break; case DBConstants.WORD_OBJECT_TYPE_MIDDLEGROUND: elements.add(new Landscape(blockPosition)); //Generiere random Collectables if ((int)(Math.random()*4) == 0){ elements.add(new Collectable(blockPosition,db.getRandomCollectableNumber())); } break; case DBConstants.WORD_OBJECT_TYPE_ILLUSTRATION_SMALL: elements.add(new IllustrationSmall(blockPosition,wr.getImage_id())); //Generiere random Collectables if ((int)(Math.random()*4) == 0){ elements.add(new Collectable(blockPosition,db.getRandomCollectableNumber())); } break; case DBConstants.WORD_OBJECT_TYPE_ILLUSTRATION_BIG: elements.add(new IllustrationBig(blockPosition,wr.getImage_id())); //Generiere random Collectables if ((int)(Math.random()*4) == 0){ elements.add(new Collectable(blockPosition,db.getRandomCollectableNumber())); } break; case DBConstants.WORD_OBJECT_TYPE_NO_IMAGE: //Generiere random Collectables if ((int)(Math.random()*4) == 0){ elements.add(new Collectable(blockPosition,db.getRandomCollectableNumber())); } break; } rh = this.getScheme(word,blockPosition,wr); if(rh != null) renderHint.add(rh); } catch (SQLException e) { // TODO Auto-generated catch block System.out.println(word_short); } elements.add(new Word(word,blockPosition)); blockPosition += numberOfBlocks; //calculates the beginning of each new word loadingPanel.update(); } blockPosition++; storyInfo.setNumberOfBlocks(blockPosition); //add Fahnen for the End of the game elements.add(new IllustrationBig(blockPosition,Ressources.ENDINGID)); //analyze RenderHint --> are the blocks ok? or are the schemes coming to close in some parts of the story //one Scheme has a minimum size of 16 kacheln //renderHint = this.calculateImportanceOfSchemes(renderHint); renderHint = this.calcNewBlockPositions(renderHint,blockPosition); //insert renderHints in elements for(int i=0;i<renderHint.size();i++){ elements.add(renderHint.get(i)); } //end of analyzing RenderHint Collections.sort(elements, new Comparator<ILevelAppearance>() { //sort the arraylist descending @Override public int compare(ILevelAppearance la1, ILevelAppearance la2) { return ((Integer)(la1.getBlock())).compareTo((Integer)(la2.getBlock())); } }); storyInfo.setElements(elements); db.insertStoryInfoToDatabase(storyInfo); //TODO: einkommentieren return storyInfo; } /* * @author Miriam * if the schemes are coming to close after each other their position has to be modified */ private ArrayList<RenderHint> calcNewBlockPositions(ArrayList<RenderHint> renderHint, int numberOfBlocks){ if(renderHint.size() > 0){ //the startpoint of the first scheme is always fix /*if(renderHint.get(0).getBlock() < Ressources.TILESPERPANEL/2) renderHint.get(0).setBlock(0); else renderHint.get(0).setBlock(renderHint.get(0).getBlock() - Ressources.TILESPERPANEL/2);*/ if(renderHint.get(0).getBlock() % 4 != 0){ renderHint.get(0).setBlock(renderHint.get(0).getBlock()/4); } for(int i=1;i<renderHint.size();i++){ renderHint.get(i).setBlock(renderHint.get(i).getBlock()/4); if(renderHint.get(i).getBlock() <= renderHint.get(i-1).getBlock()){ renderHint.remove(i); i--; } // if(renderHint.get(i).getBlock() - renderHint.get(i-1).getBlock() < 5) // renderHint.get(i).setBlock(renderHint.get(i).getBlock() + 5); /*//if the distance of 2 schemes is between 24 and 160 if((renderHint.get(i).getBlock() - renderHint.get(i-1).getBlock() > 3*Ressources.TILESPERPANEL/2) && (renderHint.get(i).getBlock() - renderHint.get(i-1).getBlock() <= Ressources.MAXLENGTHOFSCHEME)) renderHint.get(i).setBlock(renderHint.get(i).getBlock() - Ressources.TILESPERPANEL/2); //if the distance of 2 schemes is between 16 and 24 --> new block position can't be less 8 like in the case above else if(renderHint.get(i).getBlock() - renderHint.get(i-1).getBlock() > Ressources.TILESPERPANEL) renderHint.get(i).setBlock(renderHint.get(i-1).getBlock() + Ressources.TILESPERPANEL); //if the distance of 2 schemes is bigger than 160 else if(renderHint.get(i).getBlock() - renderHint.get(i-1).getBlock() > Ressources.MAXLENGTHOFSCHEME){ //insert RenderHint with the scheme NONE if(renderHint.get(i).getBlock() - renderHint.get(i-1).getBlock() > Ressources.MAXLENGTHOFSCHEME + Ressources.TILESPERPANEL/2) renderHint.add(i,new RenderHint(renderHint.get(i-1).getBlock()+Ressources.MAXLENGTHOFSCHEME, RenderHint.RENDERHINT_NONE, 1)); else renderHint.add(i,new RenderHint(renderHint.get(i-1).getBlock()+Ressources.MAXLENGTHOFSCHEME - Ressources.TILESPERPANEL/2, RenderHint.RENDERHINT_NONE, 1)); i++; renderHint.get(i).setBlock(renderHint.get(i).getBlock() - Ressources.TILESPERPANEL/2); } //else //renderHint.remove(i);*/ } } return renderHint; } /* * @author Miriam * if same schemes are coming exactly after each other then the importance should be increased */ private ArrayList<RenderHint> calculateImportanceOfSchemes(ArrayList<RenderHint> renderHint){ RenderHint rh; for(int i=1;i<renderHint.size();i++){ rh = renderHint.get(i-1); if(renderHint.get(i).getRenderHint() == rh.getRenderHint()){ renderHint.get(i-1).setImportance(renderHint.get(i-1).getImportance()+1); //increase Importance renderHint.remove(i); i--; } } return renderHint; } /* * @author Miriam * analyzes if the words indicates a scheme, eg. Water, Mountains, ... for the Foreground */ private RenderHint getScheme(String word, int block, WordResult wr) throws SQLException{ RenderHint rh; ArrayList[] rs = wr.getResultSet(); if(rs.length > 0){ ArrayList<String> stringResults = rs[0]; for(String s : stringResults){ for(int i=0;i<RenderHint.WORDGROUP_LENGTH;i++){ if((RenderHint.WORDGROUP_FOREST.length>i) && s.contains(RenderHint.WORDGROUP_FOREST[i])){ rh = new RenderHint(block,RenderHint.RENDERHINT_FOREST,1); return rh; } else if((RenderHint.WORDGROUP_CITY.length>i) && s.contains(RenderHint.WORDGROUP_CITY[i])){ rh = new RenderHint(block,RenderHint.RENDERHINT_CITY,1); return rh; } else if((RenderHint.WORDGROUP_VILLAGE.length>i) && s.contains(RenderHint.WORDGROUP_VILLAGE[i])){ rh = new RenderHint(block,RenderHint.RENDERHINT_VILLAGE,1); return rh; } else if((RenderHint.WORDGROUP_CASTLE.length>i) && s.contains(RenderHint.WORDGROUP_CASTLE[i])){ rh = new RenderHint(block,RenderHint.RENDERHINT_CASTLE,1); return rh; } else if((RenderHint.WORDGROUP_LANDSCAPE.length>i) && s.contains(RenderHint.WORDGROUP_LANDSCAPE[i])){ rh = new RenderHint(block,RenderHint.RENDERHINT_LANDSCAPE,1); return rh; } } } } return null; } /** * @author Martika * @param word * @return width in pixel */ public int numberOfPixelsOfString(String word){ int pixelWidth = 0; Graphics2D g = (Graphics2D) new BufferedImage(1,1,1).getGraphics(); g.setFont(storyTextFont); FontMetrics fm = g.getFontMetrics(); java.awt.geom.Rectangle2D rect = fm.getStringBounds(word, g); pixelWidth = (int)Math.ceil((rect.getWidth())); pixelWidth = (int) (pixelWidth + Math.ceil(3*Ressources.SCALE)); return pixelWidth; } //TODO Methode schreiben /*public File generateLevelFile(){ * * } */ }