/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.recovery_l10n;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.HashMap;

/**
 * This activity assists in generating the specially-formatted bitmaps
 * of text needed for recovery's localized text display.  Each image
 * contains all the translations of a single string; above each
 * translation is a "header row" that encodes that subimage's width,
 * height, and locale using pixel values.
 *
 * To use this app to generate new translations:
 *
 *   - Update the string resources in res/values-*
 *
 *   - Update the list of desired locales (mLocales) below.  Locales
 *     should be ordered by decreasing popularity (ie, the most
 *     commonly-used one first).
 *
 *   - Build and run the app.  Select the string you want to
 *     translate, and press the "Go" button.
 *
 *   - Wait for it to finish cycling through all the strings, then
 *     pull /data/data/com.android.recovery_l10n/files/text-out.png
 *     from the device.
 *
 *   - "pngcrush -c 0 text-out.png output.png"
 *
 *   - Put output.png in bootable/recovery/res/images/ (renamed
 *     appropriately).
 *
 * Recovery expects 8-bit 1-channel images (white text on black
 * background).  pngcrush -c 0 will convert the output of this program
 * to such an image.  If you use any other image handling tools,
 * remember that they must be lossless to preserve the exact values of
 * pixels in the header rows; don't convert them to jpeg or anything.
 */

public class Main extends Activity {
    private static final String TAG = "RecoveryL10N";

    final Locale[] mLocales = new Locale[] { Locale.US, Locale.GERMANY };

    HashMap<Locale, Bitmap> savedBitmaps;
    TextView mText;
    int mStringId = R.string.recovery_installing;

    public class TextCapture implements Runnable {
        private Locale nextLocale;
        private Locale thisLocale;
        private Runnable next;

        TextCapture(Locale thisLocale, Locale nextLocale, Runnable next) {
            this.nextLocale = nextLocale;
            this.thisLocale = thisLocale;
            this.next = next;
        }

        public void run() {
            Bitmap b = mText.getDrawingCache();
            savedBitmaps.put(thisLocale, b.copy(Bitmap.Config.ARGB_8888, false));

            if (nextLocale != null) {
                switchTo(nextLocale);
            }

            if (next != null) {
                mText.postDelayed(next, 200);
            }
        }
    }

    private void switchTo(Locale locale) {
        Resources standardResources = getResources();
        AssetManager assets = standardResources.getAssets();
        DisplayMetrics metrics = standardResources.getDisplayMetrics();
        Configuration config = new Configuration(standardResources.getConfiguration());
        config.locale = locale;
        Resources defaultResources = new Resources(assets, metrics, config);

        mText.setText(mStringId);

        mText.setDrawingCacheEnabled(false);
        mText.setDrawingCacheEnabled(true);
        mText.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    }

    @Override
    public void onCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);
        setContentView(R.layout.main);

        savedBitmaps = new HashMap<Locale, Bitmap>();

        Spinner spinner = (Spinner) findViewById(R.id.which);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            this, R.array.string_options, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView parent, View view,
                                       int pos, long id) {
                switch (pos) {
                    case 0: mStringId = R.string.recovery_installing; break;
                    case 1: mStringId = R.string.recovery_erasing; break;
                    case 2: mStringId = R.string.recovery_no_command; break;
                    case 3: mStringId = R.string.recovery_error; break;
                }
            }
            @Override public void onNothingSelected(AdapterView parent) { }
            });

        mText = (TextView) findViewById(R.id.text);

        final Runnable seq = buildSequence(mLocales);

        Button b = (Button) findViewById(R.id.go);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View ignore) {
                mText.post(seq);
            }
            });
    }

    private Runnable buildSequence(final Locale[] locales) {
        Runnable head = new Runnable() { public void run() { mergeBitmaps(locales); } };
        Locale prev = null;
        for (Locale loc : locales) {
            head = new TextCapture(loc, prev, head);
            prev = loc;
        }
        final Runnable fhead = head;
        final Locale floc = prev;
        return new Runnable() { public void run() { startSequence(fhead, floc); } };
    }

    private void startSequence(Runnable firstRun, Locale firstLocale) {
        savedBitmaps.clear();
        switchTo(firstLocale);
        mText.postDelayed(firstRun, 200);
    }

    private void saveBitmap(Bitmap b, String filename) {
        try {
            FileOutputStream fos = openFileOutput(filename, 0);
            b.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
        } catch (IOException e) {
            Log.i(TAG, "failed to write PNG", e);
        }
    }

    private int colorFor(byte b) {
        return 0xff000000 | (b<<16) | (b<<8) | b;
    }

    private int colorFor(int b) {
        return 0xff000000 | (b<<16) | (b<<8) | b;
    }

    private void mergeBitmaps(final Locale[] locales) {
        HashMap<String, Integer> countByLanguage = new HashMap<String, Integer>();

        int height = 2;
        int width = 10;
        int maxHeight = 0;
        for (Locale loc : locales) {
            Bitmap b = savedBitmaps.get(loc);
            int h = b.getHeight();
            int w = b.getWidth();
            height += h+1;
            if (h > maxHeight) maxHeight = h;
            if (w > width) width = w;

            String lang = loc.getLanguage();
            if (countByLanguage.containsKey(lang)) {
                countByLanguage.put(lang, countByLanguage.get(lang)+1);
            } else {
                countByLanguage.put(lang, 1);
            }
        }

        Log.i(TAG, "output bitmap is " + width + " x " + height);
        Bitmap out = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        out.eraseColor(0xff000000);
        int[] pixels = new int[maxHeight * width];

        int p = 0;
        for (Locale loc : locales) {
            Bitmap bm = savedBitmaps.get(loc);
            int h = bm.getHeight();
            int w = bm.getWidth();

            String lang = loc.getLanguage();
            if (countByLanguage.get(lang) > 1) {
                lang = loc.toString();
            }
            Log.i(TAG, "encoding \"" + loc + "\" as \"" + lang + "\"");
            byte[] langBytes = lang.getBytes();
            out.setPixel(0, p, colorFor(w & 0xff));
            out.setPixel(1, p, colorFor(w >>> 8));
            out.setPixel(2, p, colorFor(h & 0xff));
            out.setPixel(3, p, colorFor(h >>> 8));
            out.setPixel(4, p, colorFor(langBytes.length));
            int x = 5;
            for (byte b : langBytes) {
                out.setPixel(x, p, colorFor(b));
                x++;
            }
            out.setPixel(x, p, colorFor(0));

            p++;

            bm.getPixels(pixels, 0, w, 0, 0, w, h);
            out.setPixels(pixels, 0, w, 0, p, w, h);
            p += h;
        }

        // if no languages match, suppress text display by using a
        // single black pixel as the image.
        out.setPixel(0, p, colorFor(1));
        out.setPixel(1, p, colorFor(0));
        out.setPixel(2, p, colorFor(1));
        out.setPixel(3, p, colorFor(0));
        out.setPixel(4, p, colorFor(0));
        p++;

        saveBitmap(out, "text-out.png");
    }
}
