/*
 * Inverse.java
 *
 * Created on 2004. augusztus 22., 13:05
 */

package inverse;

//import javax.microedition.midlet.MIDlet;
//import com.siemens.mp.lcdui.Image;
//import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import java.io.IOException;
import java.io.PrintStream;

/**
 * Ez a midlet betölti a háttértárról a kep.png nevű képet,
 * és kep2.bmp néven menti a negatívját.
 * Amikor a művelet befejeződött, a program leáll.
 * Az invertálandó képnek a következő kritériumoknak kell megfelelnie:
 * - 8 bit/pixel színmélység (azaz 256 szín)
 * - PNG, JPG, GIF vagy BMP formátum (a kiterjesztés nem számít!)
 * - A kép méretére is vonatkozik v.milyen korlátozás,
 *   de 101*80 pixeles képekkel még könnyedén elbánik a telefon :-)
 *
 * A pixelek színe ARGB formátumban van megadva: 0xAARRGGBB, ahol AA (alpha)
 * az átlátszóság (átlátszatlanság) mértékét jelöli. Értéke 00 és FF közötti.
 * A 00 teljesen átlátszó (vagyis láthatatlan) pixelt, FF teljesen átlátszatlan
 * pixelt jelöl. RR, GG és BB a vörös, a zöld és a kék komponenseket jelöli.
 * Az inverz kiszámítására a következő algoritmust használja:
 * (color az eredeti szín)
 * int a = ((color >> 24) & 255);
 * int r = 255 - ((color >> 16) & 255);
 * int g = 255 - ((color >> 8) & 255);
 * int b = 255 - (color & 255);
 * az inverz: ( (a << 24) | (r << 16) | (g << 8) | b );
 *
 * FONTOS: Siemens MC60-nál régebbi típusú készüléken nem fut!
 *
 * @author ZnOS
 * @version 2.0
 */
public class Inverse extends javax.microedition.midlet.MIDlet {
    
    /** Az invertálandó kép */
    private javax.microedition.lcdui.Image image;
    /** A képernyőn megjelenő 'ablak' */
    private Form form;
    /** A folymatjelző */
    private Gauge progressBar;
    
    /**
     * A program elindításakor ez a metódus automatikusan meghívódik.
     */
    public void startApp() {
        
        /* A képernyőn megjelenő 'ablak' létrehozása... */
        this.form = new Form("Inverse");
        /* ... és megjelenítése */
        Display.getDisplay(this).setCurrent(this.form);
        
        try {
            /* Kép betöltése. A kép elérési útvonalát és nevét (beleértve a kiterjesztést is)
               a fenti kritériumoknak megfelelően lehet módosítani! */
            this.image = com.siemens.mp.lcdui.Image.createImageFromFile("a:/kep.png", false);
            
            /* A betöltött kép szélessége és magassága */
            int width = this.image.getWidth();
            int height = this.image.getHeight();
            
            /* A folyamatjelző inicializálása, és hozzáadása az 'ablakhoz' */
            this.progressBar = new Gauge("Kérlek, várj türelemmel!", false, width*height, 0);
            this.form.append(this.progressBar);
            
            /* Az összes pixel színét invertáljuk */
            int i, j;
            for(i=0; i<width; i++) {
                for(j=0; j<height; j++) {
                    
                    /* A pixel eredeti színe */
                    int color = com.siemens.mp.lcdui.Image.getPixelColor(image, i, j);
                    
                    /* Végül lecseréljük az eredeti pixel eredeti színét az inverzére */
                    com.siemens.mp.lcdui.Image.setPixelColor(image, i, j,
                    (((color>>0x18)&0xFF)<<0x18)|((0xFF-((color>>0x10)&0xFF))<<
                    0x10)|((0xFF-((color>>0x08)&0xFF))<<0x08)|(0xFF-(color&0xFF))); // lásd fent
                    
                }
                /* A folyamatjelző léptetése */
                this.progressBar.setValue(i*j);
            }
            
            /* Az invertált kép mentése BMP formátumban */
            com.siemens.mp.lcdui.Image.writeBmpToFile(image, "a:/kep2.bmp");
            
        } catch(IOException ioe) {
            /* Ha a kép betöltése vagy mentése sikertelen */
            System.out.println("A hiba oka: " + ioe);
        } catch(IllegalArgumentException iae) {
            /* Egy pixel koordinátáinak hibás meghatározásakor keletkezhet */
            System.out.println("A hiba oka: " + iae);
        } finally {
            /* Program befejezése */
            this.exitApp();
        }
    }
    
    /**
     * Ha pl. egy bejövő hívás érkezik, akkor a készülék ezt a metódust hívja meg.
     * Ezt az esetet most nem kezeljük le.
     */
    public void pauseApp() {
    }
    
    /**
     * A program befejeződésekor hívódik meg.
     * @param unconditional
     */
    public void destroyApp(boolean unconditional) {
    }
    
    /**
     * Egy saját metódus a program bezárására.
     * Mielőtt kérnénk a VM-et, hogy fejezze be a program futtatását, kérünk egy szemétgyűjtést.
     */
    private void exitApp() {
        this.image = null;
        System.gc();
        destroyApp(false);
        notifyDestroyed();
    }
}


