org.kde.necessitas.ministro.ExtractStyle.java Source code

Java tutorial

Introduction

Here is the source code for org.kde.necessitas.ministro.ExtractStyle.java

Source

/*
Copyright (c) 2011, BogDan Vatra <bog_dan_ro@yahoo.com>
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.kde.necessitas.ministro;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.NinePatchDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.inputmethod.EditorInfo;

public class ExtractStyle {

    native static int[] extractChunkInfo(byte[] chunkData);

    native static int[] extract9PatchInfo(Object ninePatchDrawable);

    native static Object getClipStateDrawableObject(Object clipStateObject);

    Class<?> styleableClass = getStylableClass();
    final int[] EMPTY_STATE_SET = {};
    final int[] ENABLED_STATE_SET = { android.R.attr.state_enabled };
    final int[] FOCUSED_STATE_SET = { android.R.attr.state_focused };
    final int[] SELECTED_STATE_SET = { android.R.attr.state_selected };
    final int[] PRESSED_STATE_SET = { android.R.attr.state_pressed };
    final int[] WINDOW_FOCUSED_STATE_SET = { android.R.attr.state_window_focused };
    final int[] ENABLED_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, FOCUSED_STATE_SET);
    final int[] ENABLED_SELECTED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, SELECTED_STATE_SET);
    final int[] ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] FOCUSED_SELECTED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, SELECTED_STATE_SET);
    final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
    final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_SELECTED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_SELECTED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(
            ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, SELECTED_STATE_SET);
    final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_SELECTED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, FOCUSED_STATE_SET);
    final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
    final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(
            PRESSED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_ENABLED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, ENABLED_STATE_SET);
    final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_ENABLED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, SELECTED_STATE_SET);
    final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(
            PRESSED_ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_ENABLED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, FOCUSED_STATE_SET);
    final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET,
            WINDOW_FOCUSED_STATE_SET);
    final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET,
            SELECTED_STATE_SET);
    final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(
            PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);

    final int View_background = getField(styleableClass, "View_background");
    final int View_padding = getField(styleableClass, "View_padding");
    final int View_paddingLeft = getField(styleableClass, "View_paddingLeft");
    final int View_paddingTop = getField(styleableClass, "View_paddingTop");
    final int View_paddingRight = getField(styleableClass, "View_paddingRight");
    final int View_paddingBottom = getField(styleableClass, "View_paddingBottom");
    final int View_scrollX = getField(styleableClass, "View_scrollX");
    final int View_scrollY = getField(styleableClass, "View_scrollY");
    final int View_id = getField(styleableClass, "View_id");
    final int View_tag = getField(styleableClass, "View_tag");
    final int View_fitsSystemWindows = getField(styleableClass, "View_fitsSystemWindows");
    final int View_focusable = getField(styleableClass, "View_focusable");
    final int View_focusableInTouchMode = getField(styleableClass, "View_focusableInTouchMode");
    final int View_clickable = getField(styleableClass, "View_clickable");
    final int View_longClickable = getField(styleableClass, "View_longClickable");
    final int View_saveEnabled = getField(styleableClass, "View_saveEnabled");
    final int View_duplicateParentState = getField(styleableClass, "View_duplicateParentState");
    final int View_visibility = getField(styleableClass, "View_visibility");
    final int View_drawingCacheQuality = getField(styleableClass, "View_drawingCacheQuality");
    final int View_contentDescription = getField(styleableClass, "View_contentDescription");
    final int View_soundEffectsEnabled = getField(styleableClass, "View_soundEffectsEnabled");
    final int View_hapticFeedbackEnabled = getField(styleableClass, "View_hapticFeedbackEnabled");
    final int View_scrollbars = getField(styleableClass, "View_scrollbars");
    final int View_fadingEdge = getField(styleableClass, "View_fadingEdge");
    final int View_scrollbarStyle = getField(styleableClass, "View_scrollbarStyle");
    final int View_isScrollContainer = getField(styleableClass, "View_isScrollContainer");
    final int View_keepScreenOn = getField(styleableClass, "View_keepScreenOn");
    final int View_filterTouchesWhenObscured = getField(styleableClass, "View_filterTouchesWhenObscured");
    final int View_nextFocusLeft = getField(styleableClass, "View_nextFocusLeft");
    final int View_nextFocusRight = getField(styleableClass, "View_nextFocusRight");
    final int View_nextFocusUp = getField(styleableClass, "View_nextFocusUp");
    final int View_nextFocusDown = getField(styleableClass, "View_nextFocusDown");
    final int View_minWidth = getField(styleableClass, "View_minWidth");
    final int View_minHeight = getField(styleableClass, "View_minHeight");
    final int View_onClick = getField(styleableClass, "View_onClick");
    final int View_overScrollMode = getField(styleableClass, "View_overScrollMode");

    final int TextAppearance_textColorHighlight = getField(styleableClass, "TextAppearance_textColorHighlight");
    final int TextAppearance_textColor = getField(styleableClass, "TextAppearance_textColor");
    final int TextAppearance_textColorHint = getField(styleableClass, "TextAppearance_textColorHint");
    final int TextAppearance_textColorLink = getField(styleableClass, "TextAppearance_textColorLink");
    final int TextAppearance_textSize = getField(styleableClass, "TextAppearance_textSize");
    final int TextAppearance_typeface = getField(styleableClass, "TextAppearance_typeface");
    final int TextAppearance_textStyle = getField(styleableClass, "TextAppearance_textStyle");
    final int TextAppearance_textAllCaps = getField(styleableClass, "TextAppearance_textAllCaps");
    final int TextView_editable = getField(styleableClass, "TextView_editable");
    final int TextView_inputMethod = getField(styleableClass, "TextView_inputMethod");
    final int TextView_numeric = getField(styleableClass, "TextView_numeric");
    final int TextView_digits = getField(styleableClass, "TextView_digits");
    final int TextView_phoneNumber = getField(styleableClass, "TextView_phoneNumber");
    final int TextView_autoText = getField(styleableClass, "TextView_autoText");
    final int TextView_capitalize = getField(styleableClass, "TextView_capitalize");
    final int TextView_bufferType = getField(styleableClass, "TextView_bufferType");
    final int TextView_selectAllOnFocus = getField(styleableClass, "TextView_selectAllOnFocus");
    final int TextView_autoLink = getField(styleableClass, "TextView_autoLink");
    final int TextView_linksClickable = getField(styleableClass, "TextView_linksClickable");
    final int TextView_drawableLeft = getField(styleableClass, "TextView_drawableLeft");
    final int TextView_drawableTop = getField(styleableClass, "TextView_drawableTop");
    final int TextView_drawableRight = getField(styleableClass, "TextView_drawableRight");
    final int TextView_drawableBottom = getField(styleableClass, "TextView_drawableBottom");
    final int TextView_drawableStart = getField(styleableClass, "TextView_drawableStart");
    final int TextView_drawableEnd = getField(styleableClass, "TextView_drawableEnd");
    final int TextView_drawablePadding = getField(styleableClass, "TextView_drawablePadding");
    final int TextView_textCursorDrawable = getField(styleableClass, "TextView_textCursorDrawable");
    final int TextView_maxLines = getField(styleableClass, "TextView_maxLines");
    final int TextView_maxHeight = getField(styleableClass, "TextView_maxHeight");
    final int TextView_lines = getField(styleableClass, "TextView_lines");
    final int TextView_height = getField(styleableClass, "TextView_height");
    final int TextView_minLines = getField(styleableClass, "TextView_minLines");
    final int TextView_minHeight = getField(styleableClass, "TextView_minHeight");
    final int TextView_maxEms = getField(styleableClass, "TextView_maxEms");
    final int TextView_maxWidth = getField(styleableClass, "TextView_maxWidth");
    final int TextView_ems = getField(styleableClass, "TextView_ems");
    final int TextView_width = getField(styleableClass, "TextView_width");
    final int TextView_minEms = getField(styleableClass, "TextView_minEms");
    final int TextView_minWidth = getField(styleableClass, "TextView_minWidth");
    final int TextView_gravity = getField(styleableClass, "TextView_gravity");
    final int TextView_hint = getField(styleableClass, "TextView_hint");
    final int TextView_text = getField(styleableClass, "TextView_text");
    final int TextView_scrollHorizontally = getField(styleableClass, "TextView_scrollHorizontally");
    final int TextView_singleLine = getField(styleableClass, "TextView_singleLine");
    final int TextView_ellipsize = getField(styleableClass, "TextView_ellipsize");
    final int TextView_marqueeRepeatLimit = getField(styleableClass, "TextView_marqueeRepeatLimit");
    final int TextView_includeFontPadding = getField(styleableClass, "TextView_includeFontPadding");
    final int TextView_cursorVisible = getField(styleableClass, "TextView_cursorVisible");
    final int TextView_maxLength = getField(styleableClass, "TextView_maxLength");
    final int TextView_textScaleX = getField(styleableClass, "TextView_textScaleX");
    final int TextView_freezesText = getField(styleableClass, "TextView_freezesText");
    final int TextView_shadowColor = getField(styleableClass, "TextView_shadowColor");
    final int TextView_shadowDx = getField(styleableClass, "TextView_shadowDx");
    final int TextView_shadowDy = getField(styleableClass, "TextView_shadowDy");
    final int TextView_shadowRadius = getField(styleableClass, "TextView_shadowRadius");
    final int TextView_enabled = getField(styleableClass, "TextView_enabled");
    final int TextView_textColorHighlight = getField(styleableClass, "TextView_textColorHighlight");
    final int TextView_textColor = getField(styleableClass, "TextView_textColor");
    final int TextView_textColorHint = getField(styleableClass, "TextView_textColorHint");
    final int TextView_textColorLink = getField(styleableClass, "TextView_textColorLink");
    final int TextView_textSize = getField(styleableClass, "TextView_textSize");
    final int TextView_typeface = getField(styleableClass, "TextView_typeface");
    final int TextView_textStyle = getField(styleableClass, "TextView_textStyle");
    final int TextView_password = getField(styleableClass, "TextView_password");
    final int TextView_lineSpacingExtra = getField(styleableClass, "TextView_lineSpacingExtra");
    final int TextView_lineSpacingMultiplier = getField(styleableClass, "TextView_lineSpacingMultiplier");
    final int TextView_inputType = getField(styleableClass, "TextView_inputType");
    final int TextView_imeOptions = getField(styleableClass, "TextView_imeOptions");
    final int TextView_imeActionLabel = getField(styleableClass, "TextView_imeActionLabel");
    final int TextView_imeActionId = getField(styleableClass, "TextView_imeActionId");
    final int TextView_privateImeOptions = getField(styleableClass, "TextView_privateImeOptions");
    final int TextView_textSelectHandleLeft = getField(styleableClass, "TextView_textSelectHandleLeft");
    final int TextView_textSelectHandleRight = getField(styleableClass, "TextView_textSelectHandleRight");
    final int TextView_textSelectHandle = getField(styleableClass, "TextView_textSelectHandle");
    final int TextView_textIsSelectable = getField(styleableClass, "TextView_textIsSelectable");
    final int TextView_textAllCaps = getField(styleableClass, "TextView_textAllCaps");

    final int ImageView_src = getField(styleableClass, "ImageView_src");
    final int ImageView_baselineAlignBottom = getField(styleableClass, "ImageView_baselineAlignBottom");
    final int ImageView_adjustViewBounds = getField(styleableClass, "ImageView_adjustViewBounds");
    final int ImageView_maxWidth = getField(styleableClass, "ImageView_maxWidth");
    final int ImageView_maxHeight = getField(styleableClass, "ImageView_maxHeight");
    final int ImageView_scaleType = getField(styleableClass, "ImageView_scaleType");
    final int ImageView_tint = getField(styleableClass, "ImageView_tint");
    final int ImageView_cropToPadding = getField(styleableClass, "ImageView_cropToPadding");

    final Resources.Theme m_theme;
    final String m_extractPath;
    Context m_context;

    class FakeCanvas extends Canvas {
        int[] chunkData = null;

        class Size {
            public int s, e;

            Size(int start, int end) {
                s = start;
                e = end;
            }
        }

        public boolean isHardwareAccelerated() {
            return true;
        }

        public void drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint) {
            chunkData = extractChunkInfo(chunks);
        }
    }

    private int[] stateSetUnion(final int[] stateSet1, final int[] stateSet2) {
        try {
            final int stateSet1Length = stateSet1.length;
            final int stateSet2Length = stateSet2.length;
            final int[] newSet = new int[stateSet1Length + stateSet2Length];
            int k = 0;
            int i = 0;
            int j = 0;
            // This is a merge of the two input state sets and assumes that the
            // input sets are sorted by the order imposed by ViewDrawableStates.
            int[] viewDrawableStatesState = (int[]) styleableClass.getDeclaredField("ViewDrawableStates").get(null);
            for (int viewState : viewDrawableStatesState) {
                if (i < stateSet1Length && stateSet1[i] == viewState) {
                    newSet[k++] = viewState;
                    i++;
                } else if (j < stateSet2Length && stateSet2[j] == viewState) {
                    newSet[k++] = viewState;
                    j++;
                }
                if (k > 1) {
                    assert (newSet[k - 1] > newSet[k - 2]);
                }
            }
            return newSet;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Class<?> getStylableClass() {
        try {
            return Class.forName("android.R$styleable");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    int getField(Class<?> clazz, String fieldName) {
        try {
            return clazz.getDeclaredField(fieldName).getInt(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    JSONObject getColorStateList(ColorStateList colorList) {
        JSONObject json = new JSONObject();
        try {
            json.put("EMPTY_STATE_SET", colorList.getColorForState(EMPTY_STATE_SET, 0));
            json.put("WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(WINDOW_FOCUSED_STATE_SET, 0));
            json.put("SELECTED_STATE_SET", colorList.getColorForState(SELECTED_STATE_SET, 0));
            json.put("SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_STATE_SET, 0));
            json.put("FOCUSED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_STATE_SET, 0));
            json.put("FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("ENABLED_STATE_SET", colorList.getColorForState(ENABLED_STATE_SET, 0));
            json.put("ENABLED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(ENABLED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("ENABLED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_STATE_SET, 0));
            json.put("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_STATE_SET, 0));
            json.put("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("ENABLED_FOCUSED_SELECTED_STATE_SET",
                    colorList.getColorForState(ENABLED_FOCUSED_SELECTED_STATE_SET, 0));
            json.put("ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_STATE_SET", colorList.getColorForState(PRESSED_STATE_SET, 0));
            json.put("PRESSED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_STATE_SET, 0));
            json.put("PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_FOCUSED_SELECTED_STATE_SET",
                    colorList.getColorForState(PRESSED_FOCUSED_SELECTED_STATE_SET, 0));
            json.put("PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_SELECTED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_SELECTED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, 0));
            json.put("PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET",
                    colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return json;
    }

    final int[] DrawableStates = { android.R.attr.state_active, android.R.attr.state_checked,
            android.R.attr.state_enabled, android.R.attr.state_focused, android.R.attr.state_pressed,
            android.R.attr.state_selected, android.R.attr.state_window_focused, 16908288 };
    final String[] DrawableStatesLabels = { "active", "checked", "enabled", "focused", "pressed", "selected",
            "window_focused", "backdroud" };
    final String[] DisableDrawableStatesLabels = { "inactive", "unchecked", "disabled", "not_focused", "no_pressed",
            "unselected", "window_not_focused", "backdroud" };

    String getFileName(String file, String[] states) {
        for (String state : states)
            file += "__" + state;
        return file;
    }

    String getStatesName(String[] states) {
        String statesName = "";
        for (String state : states) {
            if (statesName.length() > 0)
                statesName += "__";
            statesName += state;
        }
        return statesName;
    }

    void addDrawableItemIfNotExists(JSONObject json, ArrayList<Integer> list, Drawable item, String[] states,
            String filename) {
        for (Integer it : list) {
            if (it.equals(item.hashCode()))
                return;
        }
        list.add(item.hashCode());
        try {
            json.put(getStatesName(states), getDrawable(item, getFileName(filename, states)));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    void addSolution(String filename, JSONObject json, int c, Drawable drawable, ArrayList<Integer> drawableList,
            int u) {
        int pos = 0;
        int states[] = new int[c];
        String[] statesText = new String[c];

        for (int n = 0; u > 0; ++n, u >>= 1)
            if ((u & 1) > 0) {
                statesText[pos] = DrawableStatesLabels[n];
                states[pos++] = DrawableStates[n];
            }
        drawable.setState(states);
        addDrawableItemIfNotExists(json, drawableList, drawable.getCurrent(), statesText, filename);
    }

    int bitCount(int u) {
        int n;
        for (n = 0; u > 0; ++n, u &= (u - 1))
            ;
        return n;
    }

    Object getStateListDrawable_old(Drawable drawable, String filename) {
        JSONObject json = new JSONObject();
        ArrayList<Integer> drawableList = new ArrayList<Integer>();
        drawable.setState(EMPTY_STATE_SET);
        try {
            json.put("empty", getDrawable(drawable.getCurrent(), filename));
            drawableList.add(drawable.getCurrent().hashCode());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        for (int c = 1; c <= DrawableStates.length; c++)
            for (int u = 0; u < 1 << DrawableStates.length; u++)
                if (bitCount(u) == c)
                    addSolution(filename, json, c, drawable, drawableList, u);
        return json;
    }

    JSONObject getStatesList(int[] states) throws JSONException {
        JSONObject json = new JSONObject();
        for (int s : states) {
            boolean found = false;
            for (int d = 0; d < DrawableStates.length; d++) {
                if (s == DrawableStates[d]) {
                    json.put(DrawableStatesLabels[d], true);
                    found = true;
                    break;
                } else if (s == -DrawableStates[d]) {
                    json.put(DrawableStatesLabels[d], false);

                    found = true;
                    break;
                }
            }
            if (!found) {
                json.put("unhandled_state_" + s, s > 0);
            }
        }
        return json;
    }

    String getStatesName(int[] states) {
        String statesName = "";
        for (int s : states) {
            boolean found = false;
            for (int d = 0; d < DrawableStates.length; d++) {
                if (s == DrawableStates[d]) {
                    if (statesName.length() > 0)
                        statesName += "__";
                    statesName += DrawableStatesLabels[d];
                    found = true;
                    break;
                } else if (s == -DrawableStates[d]) {
                    if (statesName.length() > 0)
                        statesName += "__";
                    statesName += DisableDrawableStatesLabels[d];
                    found = true;
                    break;
                }
            }
            if (!found) {
                if (statesName.length() > 0)
                    statesName += ";";
                statesName += s;
            }
        }
        if (statesName.length() > 0)
            return statesName;
        return "empty";
    }

    private JSONObject getLayerDrawable(Object drawable, String filename) {
        JSONObject json = new JSONObject();
        LayerDrawable layers = (LayerDrawable) drawable;
        final int nr = layers.getNumberOfLayers();
        try {
            JSONArray array = new JSONArray();
            for (int i = 0; i < nr; i++) {
                JSONObject layerJsonObject = getDrawable(layers.getDrawable(i), filename + "__" + layers.getId(i));
                layerJsonObject.put("id", layers.getId(i));
                array.put(layerJsonObject);
            }
            json.put("type", "layer");
            Rect padding = new Rect();
            if (layers.getPadding(padding))
                json.put("padding", getJsonRect(padding));
            json.put("layers", array);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }

    private JSONObject getStateListDrawable(Object drawable, String filename) {
        JSONObject json = new JSONObject();
        try {
            StateListDrawable stateList = (StateListDrawable) drawable;
            final int numStates = (Integer) StateListDrawable.class.getMethod("getStateCount").invoke(stateList);
            JSONArray array = new JSONArray();
            for (int i = 0; i < numStates; i++) {
                JSONObject stateJson = new JSONObject();
                final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE)
                        .invoke(stateList, i);
                final int[] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE)
                        .invoke(stateList, i);
                stateJson.put("states", getStatesList(states));
                stateJson.put("drawable", getDrawable(d, filename + "__" + getStatesName(states)));
                array.put(stateJson);
            }
            json.put("type", "stateslist");
            Rect padding = new Rect();
            if (stateList.getPadding(padding))
                json.put("padding", getJsonRect(padding));
            json.put("stateslist", array);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    private JSONObject getGradientDrawable(GradientDrawable drawable) {
        JSONObject json = new JSONObject();
        try {
            json.put("type", "gradient");
            Object obj = drawable.getConstantState();
            Class<?> gradientStateClass = obj.getClass();
            json.put("shape", gradientStateClass.getField("mShape").getInt(obj));
            json.put("gradient", gradientStateClass.getField("mGradient").getInt(obj));
            GradientDrawable.Orientation orientation = (Orientation) gradientStateClass.getField("mOrientation")
                    .get(obj);
            json.put("orientation", orientation.name());
            int[] intArray = (int[]) gradientStateClass.getField("mColors").get(obj);
            json.put("colors", getJsonArray(intArray, 0, intArray.length));
            json.put("positions", getJsonArray((float[]) gradientStateClass.getField("mPositions").get(obj)));
            json.put("solidColor", gradientStateClass.getField("mSolidColor").getInt(obj));
            json.put("strokeWidth", gradientStateClass.getField("mStrokeWidth").getInt(obj));
            json.put("strokeColor", gradientStateClass.getField("mStrokeColor").getInt(obj));
            json.put("strokeDashWidth", gradientStateClass.getField("mStrokeDashWidth").getFloat(obj));
            json.put("strokeDashGap", gradientStateClass.getField("mStrokeDashGap").getFloat(obj));
            json.put("radius", gradientStateClass.getField("mRadius").getFloat(obj));
            float[] floatArray = (float[]) gradientStateClass.getField("mRadiusArray").get(obj);
            if (floatArray != null)
                json.put("radiusArray", getJsonArray(floatArray));
            Rect rc = (Rect) gradientStateClass.getField("mPadding").get(obj);
            if (rc != null)
                json.put("padding", getJsonRect(rc));
            json.put("width", gradientStateClass.getField("mWidth").getInt(obj));
            json.put("height", gradientStateClass.getField("mHeight").getInt(obj));
            json.put("innerRadiusRatio", gradientStateClass.getField("mInnerRadiusRatio").getFloat(obj));
            json.put("thicknessRatio", gradientStateClass.getField("mThicknessRatio").getFloat(obj));
            json.put("innerRadius", gradientStateClass.getField("mInnerRadius").getInt(obj));
            json.put("thickness", gradientStateClass.getField("mThickness").getInt(obj));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    private JSONObject getJsonRect(Rect rect) throws JSONException {
        JSONObject jsonRect = new JSONObject();
        jsonRect.put("left", rect.left);
        jsonRect.put("top", rect.top);
        jsonRect.put("right", rect.right);
        jsonRect.put("bottom", rect.bottom);
        return jsonRect;

    }

    private JSONArray getJsonArray(int[] array, int pos, int len) {
        JSONArray a = new JSONArray();
        final int l = pos + len;
        for (int i = pos; i < l; i++)
            a.put(array[i]);
        return a;
    }

    private JSONArray getJsonArray(float[] array) throws JSONException {
        JSONArray a = new JSONArray();
        if (array != null)
            for (float val : array)
                a.put(val);
        return a;
    }

    private JSONObject getJsonChunkInfo(int[] chunkData) throws JSONException {
        JSONObject jsonRect = new JSONObject();
        jsonRect.put("xdivs", getJsonArray(chunkData, 3, chunkData[0]));
        jsonRect.put("ydivs", getJsonArray(chunkData, 3 + chunkData[0], chunkData[1]));
        jsonRect.put("colors", getJsonArray(chunkData, 3 + chunkData[0] + chunkData[1], chunkData[2]));
        return jsonRect;
    }

    private JSONObject findPatchesMarings(Drawable d) throws JSONException {
        if (Build.VERSION.SDK_INT >= 11) {
            FakeCanvas fc = new FakeCanvas();
            d.draw(fc);
            return getJsonChunkInfo(fc.chunkData);
        }
        return getJsonChunkInfo(extract9PatchInfo(d));
    }

    public JSONObject getDrawable(Object drawable, String filename) {
        JSONObject json = new JSONObject();
        Bitmap bmp = null;
        if (drawable instanceof Bitmap)
            bmp = (Bitmap) drawable;
        else {
            if (drawable instanceof BitmapDrawable)
                bmp = ((BitmapDrawable) drawable).getBitmap();
            else {
                if (drawable instanceof LayerDrawable) {
                    return getLayerDrawable(drawable, filename);
                }
                if (drawable instanceof StateListDrawable) {
                    return getStateListDrawable(drawable, filename);
                }
                if (drawable instanceof GradientDrawable) {
                    return getGradientDrawable((GradientDrawable) drawable);
                }
                if (drawable instanceof ClipDrawable) {
                    try {
                        json.put("type", "clipDrawable");
                        json.put("drawable",
                                getDrawable(
                                        getClipStateDrawableObject(((ClipDrawable) drawable).getConstantState()),
                                        filename));
                        Rect padding = new Rect();
                        if (((Drawable) drawable).getPadding(padding))
                            json.put("padding", getJsonRect(padding));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return json;
                }
                if (drawable instanceof ColorDrawable) {
                    bmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
                    Drawable d = (Drawable) drawable;
                    d.setBounds(0, 0, 1, 1);
                    d.draw(new Canvas(bmp));
                    Rect padding = new Rect();
                    try {
                        json.put("type", "color");
                        json.put("color", bmp.getPixel(0, 0));
                        if (d.getPadding(padding))
                            json.put("padding", getJsonRect(padding));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    return json;
                } else {
                    Drawable d = (Drawable) drawable;
                    int w = d.getIntrinsicWidth();
                    int h = d.getIntrinsicHeight();
                    d.setLevel(10000);
                    if (w < 1 || h < 1) {
                        w = 100;
                        h = 100;
                    }
                    bmp = Bitmap.createBitmap(w, h, Config.ARGB_8888);
                    d.setBounds(0, 0, w, h);
                    d.draw(new Canvas(bmp));
                    if (drawable instanceof NinePatchDrawable) {
                        NinePatchDrawable npd = (NinePatchDrawable) drawable;
                        try {
                            json.put("type", "9patch");
                            json.put("drawable", getDrawable(bmp, filename));
                            Rect padding = new Rect();
                            if (npd.getPadding(padding))
                                json.put("padding", getJsonRect(padding));
                            json.put("chunkInfo", findPatchesMarings(d));
                            return json;
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        FileOutputStream out;
        try {
            filename = m_extractPath + filename + ".png";
            out = new FileOutputStream(filename);
            bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            json.put("type", "image");
            json.put("path", filename);
            json.put("width", bmp.getWidth());
            json.put("height", bmp.getHeight());
            MinistroActivity.nativeChmode(filename, 0644);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }

    public void extractViewInformations(String styleName, int styleId, JSONObject json, String qtClassName,
            AttributeSet attribSet) {
        try {
            int[] viewAttrs;
            viewAttrs = (int[]) styleableClass.getDeclaredField("View").get(null);
            TypedArray a = m_theme.obtainStyledAttributes(attribSet, viewAttrs, styleId, 0);

            if (null != qtClassName)
                json.put("qtClass", qtClassName);

            final int N = a.getIndexCount();
            for (int i = 0; i < N; i++) {
                int attr = a.getIndex(i);
                if (attr == View_background)
                    json.put("View_background", getDrawable(a.getDrawable(attr), styleName + "_View_background"));
                else if (attr == View_padding)
                    json.put("View_padding", a.getDimensionPixelSize(attr, -1));
                else if (attr == View_paddingLeft)
                    json.put("View_paddingLeft", a.getDimensionPixelSize(attr, -1));
                else if (attr == View_paddingTop)
                    json.put("View_paddingTop", a.getDimensionPixelSize(attr, -1));
                else if (attr == View_paddingRight)
                    json.put("View_paddingRight", a.getDimensionPixelSize(attr, -1));
                else if (attr == View_paddingBottom)
                    json.put("View_paddingBottom", a.getDimensionPixelSize(attr, -1));
                else if (attr == View_scrollX)
                    json.put("View_paddingBottom", a.getDimensionPixelOffset(attr, 0));
                else if (attr == View_scrollY)
                    json.put("View_scrollY", a.getDimensionPixelOffset(attr, 0));
                else if (attr == View_id)
                    json.put("View_id", a.getResourceId(attr, -1));
                else if (attr == View_tag)
                    json.put("View_tag", a.getText(attr));
                else if (attr == View_fitsSystemWindows)
                    json.put("View_fitsSystemWindows", a.getBoolean(attr, false));
                else if (attr == View_focusable)
                    json.put("View_focusable", a.getBoolean(attr, false));
                else if (attr == View_focusableInTouchMode)
                    json.put("View_focusableInTouchMode", a.getBoolean(attr, false));
                else if (attr == View_clickable)
                    json.put("View_clickable", a.getBoolean(attr, false));
                else if (attr == View_longClickable)
                    json.put("View_longClickable", a.getBoolean(attr, false));
                else if (attr == View_saveEnabled)
                    json.put("View_saveEnabled", a.getBoolean(attr, true));
                else if (attr == View_duplicateParentState)
                    json.put("View_duplicateParentState", a.getBoolean(attr, false));
                else if (attr == View_visibility)
                    json.put("View_visibility", a.getInt(attr, 0));
                else if (attr == View_drawingCacheQuality)
                    json.put("View_drawingCacheQuality", a.getInt(attr, 0));
                else if (attr == View_drawingCacheQuality)
                    json.put("View_contentDescription", a.getString(attr));
                else if (attr == View_soundEffectsEnabled)
                    json.put("View_soundEffectsEnabled", a.getBoolean(attr, true));
                else if (attr == View_hapticFeedbackEnabled)
                    json.put("View_hapticFeedbackEnabled", a.getBoolean(attr, true));
                else if (attr == View_scrollbars)
                    json.put("View_scrollbars", a.getInt(attr, 0));
                else if (attr == View_fadingEdge)
                    json.put("View_fadingEdge", a.getInt(attr, 0));
                else if (attr == View_scrollbarStyle)
                    json.put("View_scrollbarStyle", a.getInt(attr, 0));
                else if (attr == View_isScrollContainer)
                    json.put("View_isScrollContainer", a.getBoolean(attr, false));
                else if (attr == View_keepScreenOn)
                    json.put("View_keepScreenOn", a.getBoolean(attr, false));
                else if (attr == View_filterTouchesWhenObscured)
                    json.put("View_filterTouchesWhenObscured", a.getBoolean(attr, false));
                else if (attr == View_nextFocusLeft)
                    json.put("View_nextFocusLeft", a.getResourceId(attr, -1));
                else if (attr == View_nextFocusRight)
                    json.put("View_nextFocusRight", a.getResourceId(attr, -1));
                else if (attr == View_nextFocusUp)
                    json.put("View_nextFocusUp", a.getResourceId(attr, -1));
                else if (attr == View_nextFocusDown)
                    json.put("View_nextFocusDown", a.getResourceId(attr, -1));
                else if (attr == View_minWidth)
                    json.put("View_minWidth", a.getDimensionPixelSize(attr, 0));
                else if (attr == View_minHeight)
                    json.put("View_minHeight", a.getDimensionPixelSize(attr, 0));
                else if (attr == View_onClick)
                    json.put("View_onClick", a.getString(attr));
                else if (attr == View_overScrollMode)
                    json.put("View_overScrollMode", a.getInt(attr, 1));
            }
            a.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public JSONObject extractTextAppearanceInformations(String styleName, String qtClass, AttributeSet attribSet,
            int textAppearance) {
        JSONObject json = new JSONObject();
        try {
            int textColorHighlight = 0; //
            ColorStateList textColor = null; //
            ColorStateList textColorHint = null; //
            ColorStateList textColorLink = null; //
            int textSize = 15; //
            int typefaceIndex = -1; //
            int styleIndex = -1;
            boolean allCaps = false;

            Class<?> attrClass = Class.forName("android.R$attr");
            int styleId = attrClass.getDeclaredField(styleName).getInt(null);

            extractViewInformations(styleName, styleId, json, qtClass, attribSet);

            int[] textViewAttrs = (int[]) styleableClass.getDeclaredField("TextView").get(null);
            TypedArray a = m_theme.obtainStyledAttributes(null, textViewAttrs, styleId, 0);

            TypedArray appearance = null;
            if (-1 == textAppearance)
                textAppearance = a
                        .getResourceId(styleableClass.getDeclaredField("TextView_textAppearance").getInt(null), -1);

            if (textAppearance != -1)
                appearance = m_theme.obtainStyledAttributes(textAppearance,
                        (int[]) styleableClass.getDeclaredField("TextAppearance").get(null));

            if (appearance != null) {
                int n = appearance.getIndexCount();
                for (int i = 0; i < n; i++) {
                    int attr = appearance.getIndex(i);
                    if (attr == TextAppearance_textColorHighlight)
                        textColorHighlight = appearance.getColor(attr, textColorHighlight);
                    else if (attr == TextAppearance_textColor)
                        textColor = appearance.getColorStateList(attr);
                    else if (attr == TextAppearance_textColorHint)
                        textColorHint = appearance.getColorStateList(attr);
                    else if (attr == TextAppearance_textColorLink)
                        textColorLink = appearance.getColorStateList(attr);
                    else if (attr == TextAppearance_textSize)
                        textSize = appearance.getDimensionPixelSize(attr, textSize);
                    else if (attr == TextAppearance_typeface)
                        typefaceIndex = appearance.getInt(attr, -1);
                    else if (attr == TextAppearance_textStyle)
                        styleIndex = appearance.getInt(attr, -1);
                    else if (attr == TextAppearance_textAllCaps)
                        allCaps = appearance.getBoolean(attr, false);
                }
                appearance.recycle();
            }

            int n = a.getIndexCount();

            for (int i = 0; i < n; i++) {
                int attr = a.getIndex(i);

                if (attr == TextView_editable)
                    json.put("TextView_editable", a.getBoolean(attr, false));
                else if (attr == TextView_inputMethod)
                    json.put("TextView_inputMethod", a.getText(attr));
                else if (attr == TextView_numeric)
                    json.put("TextView_numeric", a.getInt(attr, 0));
                else if (attr == TextView_digits)
                    json.put("TextView_digits", a.getText(attr));
                else if (attr == TextView_phoneNumber)
                    json.put("TextView_phoneNumber", a.getBoolean(attr, false));
                else if (attr == TextView_autoText)
                    json.put("TextView_autoText", a.getBoolean(attr, false));
                else if (attr == TextView_capitalize)
                    json.put("TextView_capitalize", a.getInt(attr, -1));
                else if (attr == TextView_bufferType)
                    json.put("TextView_bufferType", a.getInt(attr, 0));
                else if (attr == TextView_selectAllOnFocus)
                    json.put("TextView_selectAllOnFocus", a.getBoolean(attr, false));
                else if (attr == TextView_autoLink)
                    json.put("TextView_autoLink", a.getInt(attr, 0));
                else if (attr == TextView_linksClickable)
                    json.put("TextView_linksClickable", a.getBoolean(attr, true));
                else if (attr == TextView_linksClickable)
                    json.put("TextView_linksClickable", a.getBoolean(attr, true));
                else if (attr == TextView_drawableLeft)
                    json.put("TextView_drawableLeft",
                            getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableLeft"));
                else if (attr == TextView_drawableTop)
                    json.put("TextView_drawableTop",
                            getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableTop"));
                else if (attr == TextView_drawableRight)
                    json.put("TextView_drawableRight",
                            getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableRight"));
                else if (attr == TextView_drawableBottom)
                    json.put("TextView_drawableBottom",
                            getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableBottom"));
                else if (attr == TextView_drawableStart)
                    json.put("TextView_drawableStart",
                            getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableStart"));
                else if (attr == TextView_drawableEnd)
                    json.put("TextView_drawableEnd",
                            getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableEnd"));
                else if (attr == TextView_drawablePadding)
                    json.put("TextView_drawablePadding", a.getDimensionPixelSize(attr, 0));
                else if (attr == TextView_textCursorDrawable)
                    json.put("TextView_textCursorDrawable",
                            getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)),
                                    styleName + "_TextView_textCursorDrawable"));
                else if (attr == TextView_maxLines)
                    json.put("TextView_maxLines", a.getInt(attr, -1));
                else if (attr == TextView_maxHeight)
                    json.put("TextView_maxHeight", a.getDimensionPixelSize(attr, -1));
                else if (attr == TextView_lines)
                    json.put("TextView_lines", a.getInt(attr, -1));
                else if (attr == TextView_height)
                    json.put("TextView_height", a.getDimensionPixelSize(attr, -1));
                else if (attr == TextView_minLines)
                    json.put("TextView_minLines", a.getInt(attr, -1));
                else if (attr == TextView_minHeight)
                    json.put("TextView_minHeight", a.getDimensionPixelSize(attr, -1));
                else if (attr == TextView_maxEms)
                    json.put("TextView_maxEms", a.getInt(attr, -1));
                else if (attr == TextView_maxWidth)
                    json.put("TextView_maxWidth", a.getDimensionPixelSize(attr, -1));
                else if (attr == TextView_ems)
                    json.put("TextView_ems", a.getInt(attr, -1));
                else if (attr == TextView_width)
                    json.put("TextView_width", a.getDimensionPixelSize(attr, -1));
                else if (attr == TextView_minEms)
                    json.put("TextView_minEms", a.getInt(attr, -1));
                else if (attr == TextView_minWidth)
                    json.put("TextView_minWidth", a.getDimensionPixelSize(attr, -1));
                else if (attr == TextView_gravity)
                    json.put("TextView_gravity", a.getInt(attr, -1));
                else if (attr == TextView_hint)
                    json.put("TextView_hint", a.getText(attr));
                else if (attr == TextView_text)
                    json.put("TextView_text", a.getText(attr));
                else if (attr == TextView_scrollHorizontally)
                    json.put("TextView_scrollHorizontally", a.getBoolean(attr, false));
                else if (attr == TextView_singleLine)
                    json.put("TextView_singleLine", a.getBoolean(attr, false));
                else if (attr == TextView_ellipsize)
                    json.put("TextView_ellipsize", a.getInt(attr, -1));
                else if (attr == TextView_marqueeRepeatLimit)
                    json.put("TextView_marqueeRepeatLimit", a.getInt(attr, 3));
                else if (attr == TextView_includeFontPadding)
                    json.put("TextView_includeFontPadding", a.getBoolean(attr, true));
                else if (attr == TextView_cursorVisible)
                    json.put("TextView_cursorVisible", a.getBoolean(attr, true));
                else if (attr == TextView_maxLength)
                    json.put("TextView_maxLength", a.getInt(attr, -1));
                else if (attr == TextView_textScaleX)
                    json.put("TextView_textScaleX", a.getFloat(attr, 1.0f));
                else if (attr == TextView_freezesText)
                    json.put("TextView_freezesText", a.getBoolean(attr, false));
                else if (attr == TextView_shadowColor)
                    json.put("TextView_shadowColor", a.getInt(attr, 0));
                else if (attr == TextView_shadowDx)
                    json.put("TextView_shadowDx", a.getFloat(attr, 0));
                else if (attr == TextView_shadowDy)
                    json.put("TextView_shadowDy", a.getFloat(attr, 0));
                else if (attr == TextView_shadowRadius)
                    json.put("TextView_shadowRadius", a.getFloat(attr, 0));
                else if (attr == TextView_enabled)
                    json.put("TextView_enabled", a.getBoolean(attr, true));
                else if (attr == TextView_textColorHighlight)
                    textColorHighlight = a.getColor(attr, textColorHighlight);
                else if (attr == TextView_textColor)
                    textColor = a.getColorStateList(attr);
                else if (attr == TextView_textColorHint)
                    textColorHint = a.getColorStateList(attr);
                else if (attr == TextView_textColorLink)
                    textColorLink = a.getColorStateList(attr);
                else if (attr == TextView_textSize)
                    textSize = a.getDimensionPixelSize(attr, textSize);
                else if (attr == TextView_typeface)
                    typefaceIndex = a.getInt(attr, typefaceIndex);
                else if (attr == TextView_textStyle)
                    styleIndex = a.getInt(attr, styleIndex);
                else if (attr == TextView_password)
                    json.put("TextView_password", a.getBoolean(attr, false));
                else if (attr == TextView_lineSpacingExtra)
                    json.put("TextView_lineSpacingExtra", a.getDimensionPixelSize(attr, 0));
                else if (attr == TextView_lineSpacingMultiplier)
                    json.put("TextView_lineSpacingMultiplier", a.getFloat(attr, 1.0f));
                else if (attr == TextView_inputType)
                    json.put("TextView_inputType", a.getInt(attr, EditorInfo.TYPE_NULL));
                else if (attr == TextView_imeOptions)
                    json.put("TextView_imeOptions", a.getInt(attr, EditorInfo.IME_NULL));
                else if (attr == TextView_imeActionLabel)
                    json.put("TextView_imeActionLabel", a.getText(attr));
                else if (attr == TextView_imeActionId)
                    json.put("TextView_imeActionId", a.getInt(attr, 0));
                else if (attr == TextView_privateImeOptions)
                    json.put("TextView_privateImeOptions", a.getString(attr));
                else if (attr == TextView_textSelectHandleLeft && styleName.equals("textViewStyle"))
                    json.put("TextView_textSelectHandleLeft",
                            getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)),
                                    styleName + "_TextView_textSelectHandleLeft"));
                else if (attr == TextView_textSelectHandleRight && styleName.equals("textViewStyle"))
                    json.put("TextView_textSelectHandleRight",
                            getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)),
                                    styleName + "_TextView_textSelectHandleRight"));
                else if (attr == TextView_textSelectHandle && styleName.equals("textViewStyle"))
                    json.put("TextView_textSelectHandle",
                            getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)),
                                    styleName + "_TextView_textSelectHandle"));
                else if (attr == TextView_textIsSelectable)
                    json.put("TextView_textIsSelectable", a.getBoolean(attr, false));
                else if (attr == TextView_textAllCaps)
                    allCaps = a.getBoolean(attr, false);
            }
            a.recycle();

            json.put("TextAppearance_textColorHighlight", textColorHighlight);
            json.put("TextAppearance_textColor", getColorStateList(textColor));
            json.put("TextAppearance_textColorHint", getColorStateList(textColorHint));
            json.put("TextAppearance_textColorLink", getColorStateList(textColorLink));
            json.put("TextAppearance_textSize", textSize);
            json.put("TextAppearance_typeface", typefaceIndex);
            json.put("TextAppearance_textStyle", styleIndex);
            json.put("TextAppearance_textAllCaps", allCaps);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    final String[] sScaleTypeArray = { "MATRIX", "FIT_XY", "FIT_START", "FIT_CENTER", "FIT_END", "CENTER",
            "CENTER_CROP", "CENTER_INSIDE" };

    public JSONObject extractImageViewInformations(String styleName, String qtClassName) {
        JSONObject json = new JSONObject();
        try {
            Class<?> attrClass = Class.forName("android.R$attr");
            int styleId = attrClass.getDeclaredField(styleName).getInt(null);

            extractViewInformations(styleName, styleId, json, qtClassName, null);

            int[] imageViewAttrs = (int[]) styleableClass.getDeclaredField("ImageView").get(null);
            TypedArray a = m_theme.obtainStyledAttributes(null, imageViewAttrs, styleId, 0);
            Drawable d = a.getDrawable(ImageView_src);
            if (d != null)
                json.put("ImageView_src", getDrawable(d, styleName + "_ImageView_src"));

            json.put("ImageView_baselineAlignBottom", a.getBoolean(ImageView_baselineAlignBottom, false));
            json.put("ImageView_adjustViewBounds", a.getBoolean(ImageView_adjustViewBounds, false));
            json.put("ImageView_maxWidth", a.getDimensionPixelSize(ImageView_maxWidth, Integer.MAX_VALUE));
            json.put("ImageView_maxHeight", a.getDimensionPixelSize(ImageView_maxHeight, Integer.MAX_VALUE));
            int index = a.getInt(ImageView_scaleType, -1);
            if (index >= 0)
                json.put("ImageView_scaleType", sScaleTypeArray[index]);

            int tint = a.getInt(ImageView_tint, 0);
            if (tint != 0)
                json.put("ImageView_tint", tint);

            json.put("ImageView_cropToPadding", a.getBoolean(ImageView_cropToPadding, false));
            a.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;

    }

    void extractCompoundButton(JSONObject parentObject, String styleName, String qtClass) {
        JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
        Class<?> attrClass;
        try {
            attrClass = Class.forName("android.R$attr");
            int styleId = attrClass.getDeclaredField(styleName).getInt(null);
            int[] compoundButtonAttrs = (int[]) styleableClass.getDeclaredField("CompoundButton").get(null);

            TypedArray a = m_theme.obtainStyledAttributes(null, compoundButtonAttrs, styleId, 0);

            Drawable d = a.getDrawable(getField(styleableClass, "CompoundButton_button"));
            if (d != null)
                json.put("CompoundButton_button", getDrawable(d, styleName + "_CompoundButton_button"));

            a.recycle();
            parentObject.put(styleName, json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void extractProgressBarInfo(JSONObject json, String styleName) {
        Class<?> attrClass;
        try {
            attrClass = Class.forName("android.R$attr");
            int styleId = attrClass.getDeclaredField(styleName).getInt(null);
            int[] progressBarAttrs = (int[]) styleableClass.getDeclaredField("ProgressBar").get(null);

            TypedArray a = m_theme.obtainStyledAttributes(null, progressBarAttrs, styleId, 0);
            int mMinWidth = 24;
            int mMaxWidth = 48;
            int mMinHeight = 24;
            int mMaxHeight = 48;
            mMinWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minWidth"), mMinWidth);
            mMaxWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxWidth"), mMaxWidth);
            mMinHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minHeight"), mMinHeight);
            mMaxHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxHeight"), mMaxHeight);

            json.put("ProgressBar_indeterminateDuration",
                    a.getInt(getField(styleableClass, "ProgressBar_indeterminateDuration"), 4000));
            json.put("ProgressBar_minWidth", mMinWidth);
            json.put("ProgressBar_maxWidth", mMaxWidth);
            json.put("ProgressBar_minHeight", mMinHeight);
            json.put("ProgressBar_maxHeight", mMaxHeight);
            json.put("ProgressBar_progress_id", android.R.id.progress);
            json.put("ProgressBar_secondaryProgress_id", android.R.id.secondaryProgress);

            Drawable d = a.getDrawable(getField(styleableClass, "ProgressBar_progressDrawable"));
            if (d != null)
                json.put("ProgressBar_progressDrawable",
                        getDrawable(d, styleName + "_ProgressBar_progressDrawable"));

            d = a.getDrawable(getField(styleableClass, "ProgressBar_indeterminateDrawable"));
            if (d != null)
                json.put("ProgressBar_indeterminateDrawable",
                        getDrawable(d, styleName + "_ProgressBar_indeterminateDrawable"));

            a.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void extractProgressBar(JSONObject parentObject, String styleName, String qtClass) {
        JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
        try {
            extractProgressBarInfo(json, styleName);
            parentObject.put(styleName, json);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    void extractAbsSeekBar(JSONObject parentObject, String styleName, String qtClass) {
        JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
        extractProgressBarInfo(json, styleName);
        Class<?> attrClass;
        try {
            attrClass = Class.forName("android.R$attr");
            int styleId = attrClass.getDeclaredField(styleName).getInt(null);
            int[] compoundButtonAttrs = (int[]) styleableClass.getDeclaredField("SeekBar").get(null);

            TypedArray a = m_theme.obtainStyledAttributes(null, compoundButtonAttrs, styleId, 0);

            Drawable d = a.getDrawable(getField(styleableClass, "SeekBar_thumb"));
            if (d != null)
                json.put("SeekBar_thumb", getDrawable(d, styleName + "_SeekBar_thumb"));

            a.recycle();
            parentObject.put(styleName, json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    JSONObject extractCheckedTextView(AttributeSet attribSet, String itemName) {
        JSONObject json = extractTextAppearanceInformations("textViewStyle", itemName, attribSet, -1);
        try {
            Class<?> attrClass = Class.forName("android.R$attr");
            int styleId = attrClass.getDeclaredField("textViewStyle").getInt(null);
            int[] compoundButtonAttrs = (int[]) styleableClass.getDeclaredField("CheckedTextView").get(null);

            TypedArray a = m_theme.obtainStyledAttributes(attribSet, compoundButtonAttrs, styleId, 0);

            Drawable d = a.getDrawable(getField(styleableClass, "CheckedTextView_checkMark"));
            if (d != null)
                json.put("CheckedTextView_checkMark", getDrawable(d, itemName + "_CheckedTextView_checkMark"));

            a.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    private JSONObject extractItemStyle(int resourceId, String itemName, int textAppearance) {
        try {
            XmlResourceParser parser = m_context.getResources().getLayout(resourceId);
            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
                // Empty
            }

            if (type != XmlPullParser.START_TAG) {
                return null;
            }

            AttributeSet attributes = Xml.asAttributeSet(parser);
            String name = parser.getName();
            if (name.equals("TextView"))
                return extractTextAppearanceInformations("textViewStyle", itemName, attributes, textAppearance);
            if (name.equals("CheckedTextView"))
                return extractCheckedTextView(attributes, itemName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void extractItemsStyle(JSONObject json) {
        try {
            json.put("simple_list_item", extractItemStyle(android.R.layout.simple_list_item_1, "simple_list_item",
                    android.R.style.TextAppearance_Large));
            json.put("simple_list_item_checked", extractItemStyle(android.R.layout.simple_list_item_checked,
                    "simple_list_item_checked", android.R.style.TextAppearance_Large));
            json.put("simple_list_item_multiple_choice",
                    extractItemStyle(android.R.layout.simple_list_item_multiple_choice,
                            "simple_list_item_multiple_choice", android.R.style.TextAppearance_Large));
            json.put("simple_list_item_single_choice",
                    extractItemStyle(android.R.layout.simple_list_item_single_choice,
                            "simple_list_item_single_choice", android.R.style.TextAppearance_Large));
            json.put("simple_spinner_item",
                    extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item", -1));
            json.put("simple_spinner_dropdown_item", extractItemStyle(android.R.layout.simple_spinner_dropdown_item,
                    "simple_spinner_dropdown_item", android.R.style.TextAppearance_Large));
            json.put("simple_dropdown_item_1line", extractItemStyle(android.R.layout.simple_dropdown_item_1line,
                    "simple_dropdown_item_1line", android.R.style.TextAppearance_Large));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public ExtractStyle(Context context, String extractPath) {
        m_extractPath = extractPath;
        new File(m_extractPath).mkdirs();
        MinistroActivity.nativeChmode(m_extractPath, 0755);
        m_context = context;
        m_theme = context.getTheme();
        JSONObject json = new JSONObject();
        try {
            json.put("buttonStyle", extractTextAppearanceInformations("buttonStyle", "QPushButton", null, -1));
            json.put("spinnerStyle", extractTextAppearanceInformations("spinnerStyle", "QComboBox", null, -1));
            extractProgressBar(json, "progressBarStyleHorizontal", "QProgressBar");
            extractAbsSeekBar(json, "seekBarStyle", "QSlider");
            extractCompoundButton(json, "checkboxStyle", "QCheckBox");
            json.put("editTextStyle", extractTextAppearanceInformations("editTextStyle", "QLineEdit", null, -1));
            extractCompoundButton(json, "radioButtonStyle", "QRadioButton");
            json.put("textViewStyle", extractTextAppearanceInformations("textViewStyle", "QWidget", null, -1));
            extractItemsStyle(json);
            //extractCompoundButton(json, "buttonStyleToggle", null);
            //extractCompoundButton(json, "switchStyle", null);
            //json.put("imageButtonStyle", extractImageViewInformations("imageButtonStyle", null));
            OutputStreamWriter jsonWriter;
            jsonWriter = new OutputStreamWriter(new FileOutputStream(m_extractPath + "style.json"));
            jsonWriter.write(json.toString(1));
            jsonWriter.close();
            MinistroActivity.nativeChmode(m_extractPath + "style.json", 0644);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}