package readers ;
import java.awt.Color ;
import java.awt.Graphics2D ;
import java.awt.image.BufferedImage ;
import java.io.File ;
import java.io.IOException ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.regex.Pattern ;
import javax.imageio.ImageIO ;
import readers.fonts.Font ;
import readers.fonts.Glyph ;
public class DDRReader extends Reader {
final static int REGION_PADDING = 32 ;
List < Box > extraRegions = new ArrayList < > ( ) ;
static int lastJump = 0 ;
boolean failed = false ;
public DDRReader ( ) {
addRegion ( new Box ( 305 , 428 , 402 , 69 ) , NUMBER ) ; //score[0]+
addRegion ( new Box ( 603 , 565 , 133 , 37 ) , NUMBER ) ; //max combo[1]+
addRegion ( new Box ( 603 , 612 , 133 , 37 ) , NUMBER ) ; //marvelous[2]+
addRegion ( new Box ( 603 , 651 , 133 , 37 ) , NUMBER ) ; //perfect[3]+
addRegion ( new Box ( 603 , 698 , 133 , 37 ) , NUMBER ) ; //great[4]+
addRegion ( new Box ( 603 , 742 , 133 , 37 ) , NUMBER ) ; //good[5]+
addRegion ( new Box ( 603 , 787 , 133 , 37 ) , NUMBER ) ; //OK[6]+
addRegion ( new Box ( 603 , 830 , 133 , 37 ) , NUMBER ) ; //miss[7]+
addRegion ( new Box ( 603 , 876 , 133 , 37 ) , NUMBER ) ; //ex score[8]+
addRegion ( new Box ( 783 , 738 , 133 , 37 ) , NUMBER ) ; //fast[9]+
addRegion ( new Box ( 783 , 821 , 133 , 37 ) , NUMBER ) ; //slow[10]+
addRegion ( new Box ( 600 , 165 , 133 , 53 ) , NUMBER ) ; //diffnumb[11]+
addRegion ( new Box ( 577 , 91 , 174 , 36 ) ) ; //playstyle[12]
addRegion ( new Box ( 253 , 207 , 357 , 183 ) ) ; //grade[13]
addRegion ( new Box ( 756 , 432 , 411 , 38 ) ) ; //songname[14]
addRegion ( new Box ( 576 , 126 , 185 , 40 ) ) ; //difficulty text[15]
init ( ) ;
}
void ColorFilter ( int [ ] arr , int region , int width ) {
switch ( region ) {
case 0 : {
process ( arr , width ,
247 , 255 , 247 , 255 , 247 , 255 ,
200 , 255 , 200 , 255 , 200 , 255 ) ;
} break ;
case 1 : {
process ( arr , width ,
180 , 255 , 180 , 255 , 180 , 255 ,
70 , 255 , 70 , 255 , 70 , 255 ) ;
} break ;
case 2 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 3 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 4 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 5 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 6 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 7 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 8 : {
process ( arr , width ,
190 , 255 , 190 , 255 , 190 , 255 ,
140 , 255 , 140 , 255 , 140 , 255 ) ;
} break ;
case 9 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 10 : {
process ( arr , width ,
0 , 50 , 0 , 50 , 0 , 50 ,
0 , 160 , 0 , 160 , 0 , 160 ) ;
} break ;
case 11 : {
process ( arr , width ,
190 , 255 , 190 , 255 , 190 , 255 ,
140 , 255 , 140 , 255 , 140 , 255 ) ;
} break ;
case 12 : {
process ( arr , width ,
190 , 255 , 190 , 255 , 190 , 255 ,
140 , 255 , 140 , 255 , 140 , 255 ) ;
} break ;
}
}
public void interpretBoxes ( Path img , boolean testingMode ) {
/ * String dataString = readAllBoxes ( img ) ;
String [ ] data = dataString . split ( Pattern . quote ( "\n" ) ) ;
String [ ] ja_data = data [ 0 ] . split ( Pattern . quote ( ")" ) ) ;
String [ ] en_data = data [ 2 ] . split ( Pattern . quote ( ")" ) ) ;
trimAllData ( ja_data ) ;
trimAllData ( en_data ) ;
System . out . println ( Arrays . toString ( ja_data ) ) ;
System . out . println ( Arrays . toString ( en_data ) ) ; * /
int regionHeights = 0 ;
int maxWidth = 0 ;
int counter = 0 ;
for ( int i = 0 ; i < readRegions . size ( ) ; i + + ) {
regionHeights + = readRegions . get ( i ) . h + REGION_PADDING ;
if ( readRegions . get ( i ) . w > maxWidth ) {
maxWidth = readRegions . get ( i ) . w * 2 ;
}
}
try {
BufferedImage originalImg = ImageIO . read ( img . toFile ( ) ) ;
BufferedImage cutImg = new BufferedImage ( maxWidth , regionHeights , BufferedImage . TYPE_INT_ARGB ) ;
Graphics2D g = cutImg . createGraphics ( ) ;
int currentHeight = 0 ;
for ( int i = 0 ; i < readRegions . size ( ) ; i + + ) {
BufferedImage subRegion = new BufferedImage ( readRegions . get ( i ) . w , readRegions . get ( i ) . h , BufferedImage . TYPE_INT_ARGB ) ;
subRegion . setRGB ( 0 , 0 , readRegions . get ( i ) . w , readRegions . get ( i ) . h , originalImg . getRGB ( readRegions . get ( i ) . x , readRegions . get ( i ) . y , readRegions . get ( i ) . w , readRegions . get ( i ) . h , null , 0 , readRegions . get ( i ) . w ) , 0 , readRegions . get ( i ) . w ) ;
int [ ] arr = subRegion . getRGB ( 0 , 0 , readRegions . get ( i ) . w , readRegions . get ( i ) . h , null , 0 , readRegions . get ( i ) . w ) ;
//System.out.println(Arrays.toString(arr));
//System.out.println(i);
//ImageIO.write(originalImg.getSubimage(readRegions.get(i).x, readRegions.get(i).y, readRegions.get(i).w, readRegions.get(i).h),"png",new File("cut.png"));
ColorFilter ( arr , i , readRegions . get ( i ) . w ) ;
subRegion . setRGB ( 0 , 0 , readRegions . get ( i ) . w , readRegions . get ( i ) . h , arr , 0 , readRegions . get ( i ) . w ) ;
ImageIO . write ( subRegion , "png" , new File ( "sub.png" ) ) ;
cutImg . setRGB ( 0 , currentHeight , readRegions . get ( i ) . w , readRegions . get ( i ) . h , arr , 0 , readRegions . get ( i ) . w ) ;
String val = interpretImage ( subRegion , i ) ;
sig_data [ counter + + ] = val ;
if ( i = = 0 ) {
//Blank out the scores because it has commas iwn it.
arr = new int [ readRegions . get ( i ) . w * readRegions . get ( i ) . h ] ;
cutImg . setRGB ( 0 , currentHeight , readRegions . get ( i ) . w , readRegions . get ( i ) . h , arr , 0 , readRegions . get ( i ) . w ) ;
}
if ( i = = 13 ) {
Color col = new Color ( subRegion . getRGB ( 131 , 84 ) , true ) ;
ColorRange range = new ColorRange ( 130 , 135 , 130 , 135 , 130 , 135 ) ;
if ( range . colorInRange ( col ) ) {
failed = true ;
}
}
currentHeight + = readRegions . get ( i ) . h + REGION_PADDING ;
}
Path output = Paths . get ( "result.png" ) ;
ImageIO . write ( cutImg , "png" , output . toFile ( ) ) ;
if ( testingMode ) {
interpretOutput ( new String [ ] { } , new String [ ] { } , sig_data ) ;
} else {
String dataString = readAllBoxes ( output ) ;
String [ ] data = dataString . split ( Pattern . quote ( "\n" ) ) ;
String [ ] ja_data = parseOutCommas ( data [ 0 ] ) . split ( Pattern . quote ( "," ) ) ;
String [ ] en_data = parseOutCommas ( data [ 2 ] ) . split ( Pattern . quote ( "," ) ) ;
trimAllData ( ja_data ) ;
trimAllData ( en_data ) ;
System . out . println ( Arrays . toString ( ja_data ) ) ;
System . out . println ( Arrays . toString ( en_data ) ) ;
System . out . println ( Arrays . toString ( sig_data ) ) ;
interpretOutput ( ja_data , en_data , sig_data ) ;
}
g . dispose ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
//System.out.println(data[0]);
//System.out.println(data[2]);
}
private String interpretImage ( BufferedImage cutImg , int i ) {
switch ( i ) {
case 0 : {
Font f = Font . FONT_DDR_SCORE ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
if ( glyphs . size ( ) = = 9 ) {
//This is a 1,000,000 score.
glyphs . remove ( 5 ) ;
glyphs . remove ( 1 ) ;
} else
if ( glyphs . size ( ) > 4 ) {
//This is a XXX,XXX score.
glyphs . remove ( 3 ) ;
}
return f . convertGlyphs ( glyphs ) ;
}
case 1 :
case 8 : {
Font f = Font . FONT_DDR_EXCOMBO ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 9 :
case 10 : {
Font f = Font . FONT_DDR_NOTECOUNT ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
case 11 : {
Font f = Font . FONT_DDR_DIFF ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
}
return "" ;
}
String interpretResults ( String [ ] finalData ) {
for ( int i = 0 ; i < finalData . length ; i + + ) {
String [ ] splitter = finalData [ i ] . split ( Pattern . quote ( "\n" ) ) ;
switch ( i ) {
case 0 : {
score = convertToInt ( splitter ) ;
} break ;
case 1 : {
maxcombo = convertToInt ( splitter ) ;
} break ;
case 2 : {
notes [ 0 ] = convertToInt ( splitter ) ;
} break ;
case 3 : {
notes [ 1 ] = convertToInt ( splitter ) ;
} break ;
case 4 : {
notes [ 2 ] = convertToInt ( splitter ) ;
} break ;
case 5 : {
notes [ 3 ] = convertToInt ( splitter ) ;
} break ;
case 6 : {
notes [ 4 ] = convertToInt ( splitter ) ;
} break ;
case 7 : {
notes [ 5 ] = convertToInt ( splitter ) ;
} break ;
case 8 : {
other = "{\"ex\":" + convertToInt ( splitter ) ;
} break ;
case 9 : {
other = other + ",\"fast\":" + convertToInt ( splitter ) ;
} break ;
case 10 : {
other = other + ",\"slow\":" + convertToInt ( splitter ) ;
} break ;
case 11 : {
difficulty = convertToInt ( splitter ) ;
} break ;
case 12 : {
other = other + ",\"playstyle\":\"" + convertToString ( splitter ) + "\"" ;
} break ;
case 13 : {
if ( failed ) {
rank = 15 ; /*F*/
} else
if ( score > = 990000 ) { rank = 0 ; /*AAA*/ } else
if ( score > = 950000 ) { rank = 1 ; /*AA+*/ } else
if ( score > = 910000 ) { rank = 2 ; /*AA*/ } else
if ( score > = 900000 ) { rank = 3 ; /*AA-*/ } else
if ( score > = 850000 ) { rank = 4 ; /*A+*/ } else
if ( score > = 810000 ) { rank = 5 ; /*A*/ } else
if ( score > = 800000 ) { rank = 6 ; /*A-*/ } else
if ( score > = 750000 ) { rank = 7 ; /*B+*/ } else
if ( score > = 710000 ) { rank = 8 ; /*B*/ } else
if ( score > = 700000 ) { rank = 9 ; /*B-*/ } else
if ( score > = 650000 ) { rank = 10 ; /*C+*/ } else
if ( score > = 610000 ) { rank = 11 ; /*C*/ } else
if ( score > = 600000 ) { rank = 12 ; /*C-*/ } else
if ( score > = 550000 ) { rank = 13 ; /*D+*/ } else
{ rank = 14 ; /*D*/ }
} break ;
case 14 : {
title = convertToString ( splitter ) ;
} break ;
case 15 : {
other = other + ",\"diff\":\"" + convertToString ( splitter ) + "\"}" ;
} break ;
}
}
return toString ( ) ;
}
}