//--------------------------------------------
//   "BookReader"
//
//    
// "    "
//
// (c) Voolkan
//--------------------------------------------

import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;
import java.util.Stack;

import java.io.InputStream;
import java.io.EOFException;
import java.io.IOException;

public class BookReader extends MIDlet {

private Display display;       //  
private BookCanvas fCanvas;    //   


public void destroyApp(boolean flag) {
}

public void pauseApp() {
}

//   
public void startApp() {
    //     
    display = Display.getDisplay(this);
    //       
    Form form = new Form(getClass().getName());
    //     
    fCanvas = new BookCanvas();
    //    
    display.setCurrent(fCanvas);
}


//    
public class BookCanvas extends Canvas {

    private Stack PageIndex; //      
    public BookCanvas() {
        //      
        PageIndex = new Stack();
    }

    //     
    protected void paint(Graphics g) {
        //       
        int gw = g.getClipWidth();
        int gh = g.getClipHeight();

        //  
        Font font = Font.getFont(Font.FACE_MONOSPACE,
                                 Font.STYLE_PLAIN,
                                 Font.SIZE_SMALL);
        //  
        g.setFont(font);

        //  
        InputStream is = getClass().getResourceAsStream("/story.txt");
        MyDataInputStream mdis = new MyDataInputStream(is);

        int x=0,y=0;    //     
        int offset=0;   //    

        //  
        g.setColor(255,255,255);
        g.fillRect(0,0,gw,gh);
        g.setColor(0,0,0);

        //     
        if(!PageIndex.empty())
        offset=((Integer)PageIndex.peek()).intValue();

        try{
            //      
            mdis.skipBytes(offset);
        } catch(IOException ioe) {} 

        String sWord;
        do {
            //     
            sWord = mdis.readWord();
            //       
            offset+=sWord.length();
            //        
            //    
            if(x+font.stringWidth(sWord)<=gw) { 
            //  ,    
            g.drawString(sWord, x,y, g.TOP|g.LEFT);
            //       
            x+=font.stringWidth(sWord);
            //     ,   
            //      
            if (mdis.b_endLine) { y+=font.getHeight(); x=0; }
        }
        //        
        else {
            //    
            y+=font.getHeight();
            //        , 
            //     
            if(y+font.getHeight()<gh) 
                g.drawString(sWord, 0,y, g.TOP|g.LEFT);
            //      
            x=font.stringWidth(sWord); 
        }
        //    ,   
        //       
    } while(y+font.getHeight()<gh && !mdis.b_endFile);

    int index;    //   

    //     ,    
    //   ,     
    //    
    if(mdis.b_endLine) index=offset; else index=offset-sWord.length();
    //      
    if(!mdis.b_endFile) PageIndex.push(new Integer(index));
    //  
    try{
        mdis.close();
    } catch(IOException ioe) {}
}


    //    
    public void keyPressed(int keyCode){
        //   
        switch(keyCode) {
            case KEY_NUM1:
                //     
                //    
                PageIndex.pop();
                if(!PageIndex.empty()) PageIndex.pop();
                repaint();
                break;
            case KEY_NUM2:
                //  
                // (     )
                repaint();
                break;
            case KEY_NUM0:
                //     
                PageIndex.removeAllElements();
                repaint();
                break;
        }
    }
} // class BookCanvas
} // class BookReader


import java.io.InputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;

public class MyDataInputStream extends DataInputStream {

//    
private String WIN1251_TO_UNICODE = "\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\
u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0459\u203a\u045a\u045c\
u045b\u045f\u00a0\u040e\u045e\u0408\u00a4\u0490\u00a6\u00a7\u0401\u00a9\u0404\u00ab\u00ac\
u00ad\u00ae\u0407\u00b0\u00b1\u0406\u0456\u0491\u00b5\u00b6\u00b7\u0451\u2116\u0454\u00bb\
u0458\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\
u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\
u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\
u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\
u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f";

public boolean b_endLine = false; //   
public boolean b_endFile = false; //   

public MyDataInputStream(InputStream is) {
    super(is);
}


//     
public String readWord() {
    int i=0;    //     
    b_endFile = false;
    char[] word = new char[100]; //    
    try {
        //        
        do word[i++]=(char)convert(readUnsignedByte());
        while (word[i-1]!=32 && word[i-1]!=10);
    } catch(EOFException ioe) {
        //  
        i--; b_endFile = true;
    }
    catch(IOException ioe) {}
    
    //     ,  
    if(word[i-1]==10) b_endLine=true; else b_endLine=false;
    //     
    return (new String(word,0,i));
}


//     Unicode
char convert(int ch) {
    return (ch < 128) ? (char)ch : WIN1251_TO_UNICODE.charAt(ch-128);
}
}
