/*
 * 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.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;

/**
 * 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-*
 *
 *   - 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";

    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;
                    case 4: mStringId = R.string.recovery_installing_security; break;
                }
            }
            @Override public void onNothingSelected(AdapterView parent) { }
            });

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

        String[] localeNames = getAssets().getLocales();
        Arrays.sort(localeNames, new Comparator<String>() {
        // Override the string comparator so that en is sorted behind en_US.
        // As a result, en_US will be matched first in recovery.
            @Override
            public int compare(String s1, String s2) {
                if (s1.equals(s2)) {
                    return 0;
                } else if (s1.startsWith(s2)) {
                    return -1;
                } else if (s2.startsWith(s1)) {
                    return 1;
                }
                return s1.compareTo(s2);
            }
        });

        ArrayList<Locale> locales = new ArrayList<Locale>();
        for (String localeName : localeNames) {
            Log.i(TAG, "locale = " + localeName);
            if (!localeName.isEmpty()) {
                locales.add(Locale.forLanguageTag(localeName));
            }
        }

        final Runnable seq = buildSequence(locales.toArray(new Locale[0]));

        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();

            bm.getPixels(pixels, 0, w, 0, 0, w, h);

            // Find the rightmost and leftmost columns with any
            // nonblack pixels; we'll copy just that region to the
            // output image.

            int right = w;
            while (right > 1) {
                boolean all_black = true;
                for (int j = 0; j < h; ++j) {
                    if (pixels[j*w+right-1] != 0xff000000) {
                        all_black = false;
                        break;
                    }
                }
                if (all_black) {
                    --right;
                } else {
                    break;
                }
            }

            int left = 0;
            while (left < right-1) {
                boolean all_black = true;
                for (int j = 0; j < h; ++j) {
                    if (pixels[j*w+left] != 0xff000000) {
                        all_black = false;
                        break;
                    }
                }
                if (all_black) {
                    ++left;
                } else {
                    break;
                }
            }

            // Make the last country variant for a given language be
            // the catch-all for that language (because recovery will
            // take the first one that matches).
            String lang = loc.getLanguage();
            if (countByLanguage.get(lang) > 1) {
                countByLanguage.put(lang, countByLanguage.get(lang)-1);
                lang = loc.toString();
            }
            int tw = right - left;
            Log.i(TAG, "encoding \"" + loc + "\" as \"" + lang + "\": " + tw + " x " + h);
            byte[] langBytes = lang.getBytes();
            out.setPixel(0, p, colorFor(tw & 0xff));
            out.setPixel(1, p, colorFor(tw >>> 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++;

            out.setPixels(pixels, left, w, 0, p, tw, 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");
        Log.i(TAG, "wrote text-out.png");
    }
}
