001package armyc2.c2sd.renderer;
002
003import android.graphics.Bitmap;
004import android.graphics.BitmapFactory;
005import android.graphics.Canvas;
006import android.graphics.Point;
007import android.graphics.Rect;
008import android.util.Base64;
009import android.util.SparseArray;
010
011import armyc2.c2sd.renderer.utilities.ImageInfo;
012import armyc2.c2sd.renderer.utilities.MilStdAttributes;
013
014
015/**
016 * Created by michael.spinelli on 8/23/2017.
017 */
018
019public class PatternFillRenderer {
020
021
022    private static String duriBeachSlopeModerate = "iVBORw0KGgoAAAANSUhEUgAAADYAAAAzBAMAAAAupuZdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAYUExURQAAAMXFxczMzM3NzdXV1dnZ2eLi4ubm5nz94OEAAAABdFJOUwBA5thmAAAAWklEQVQ4y2NgoD8wA5PMCQgSKgTkCjuAKEMTBAkRYgIyhAxAfCNlBAkVAgJ3MMlSgCChQiMc4AtrIcywFoKFtTJmWCuPhjXJaVcIT9odDU/qpl1hPGl3SJUTACZHFZF+np+2AAAAAElFTkSuQmCC";
023    private static String duriBeachSlopeSteep = "iVBORw0KGgoAAAANSUhEUgAAABoAAAAaBAMAAABbZFH9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAVUExURQAAAJSUlKKioru7u87OztfX1+Li4hAmdeYAAAABdFJOUwBA5thmAAAAJElEQVQY02NgIB+YIpEMzEIOMJIJiAQVGGAkELghkfQHg8WdABqRBBGoXfbeAAAAAElFTkSuQmCC";
024    private static String duriBeigeStipple = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gMHhIBKQOEJ3wAAAADUExURfnz8ehEBXEAAAAMSURBVAgdY2AYjAAAAJYAASEQeSYAAAAASUVORK5CYII=";
025    private static String duriFoulGround = "iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABOUExURQAAAICAgIaGhouLi42NjZCQkJSUlJiYmJycnKCgoKWlpampqa6urrGxsbe3t7u7u7y8vMbGxsjIyMzMzNHR0djY2N/f3+Xl5evr6/Ly8oBtGtwAAAABdFJOUwBA5thmAAAA50lEQVRIx+2UwW7DMAxDySVy0iqRl7WL6v//0R2GDttR8iHoEN4JU7T0gFOngrpZBZqZZ8yFM1DJe8LbRl4ApTwS5k/SgJklk3olHRBeo8bdzArH1ZSUaGPG37KYuf4x12DT7u/k4l5Y3Fuur1bifQGAcgL28MDfsYWzu5JbOHZX213m3UZSq76xmNkenfrK8lzvzD1enusdlg9cAKVkHt7IDRBOGXNzB+D+wH/R4VAdk1CtwJz7xE6oDqstpETv5bgz/4Hq1ANV6YNqzdyacHJX8iMcux4I1YHUqgPl1aCqJ1RPvZy+AED/Df1MKozlAAAAAElFTkSuQmCC";
026    private static String duriKelp = "iVBORw0KGgoAAAANSUhEUgAAAFUAAAA5CAMAAABwHZdJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABFUExURQAAAICAgIeHh4qKio+Pj5KSkpSUlJqamp6enqGhoaenp6+vr7Gxsbi4uMDAwMjIyM/Pz9bW1tra2t7e3uDg4OXl5evr67APy9YAAAABdFJOUwBA5thmAAABCUlEQVQYGe3BQXbCMAwFwO8KXMWJI6uudP+j9kGB57AjMaw8AwzD8FnueAON6MDxJGUcx5QNG1HQgcRzQcOpoAP9msKiuNF1CjOeVbxojgYUDknUJIVF7DedDRuF8BrL+FclBVJcFUoVd1aYHXslUjwUpjhRuOBZsZfQikadKP3gIGd2NFJUHCZB0FBa0cGM1kqG7owdwzB8TsU7kOENlHCcECs2MqMDTbQ4GpnRgX9HigU3VdLp5HjihtcUEqDOxLlYzcRSLQfBhlPBa2bDlclyChlXnmLBnddMir2EMh5sDueJw0VMBXtZTI5GDpMYDlqpoFFCxmEWE1rMjuOyouG0oj9SDMPwcX/MrgqpcUsGFwAAAABJRU5ErkJggg==";
027    private static String duriRigField = "iVBORw0KGgoAAAANSUhEUgAAACwAAAAsBAMAAADsqkcyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAqUExURQAAAMDAwMTExMjIyM3NzdHR0dXV1dnZ2d3d3eHh4eXl5enp6e3t7fDw8Awi1VsAAAABdFJOUwBA5thmAAAAh0lEQVQoz2NgGAqATdAHxiwSngBj8goKCkI5TIKCojBhZqCwAIRZCGRugCpmBLKlIGxFIDMBqhokLAlhAlmCAUjC0hCmIZBZABVmBbIVIMyJQOYFmJ2GgkIH4Cok4e7mCm2AMbeFX2AYBbgBjqDCHrDYo4EXR6ThiWIsCQJ78sGV2HAkzUENAN13GlU/PHOyAAAAAElFTkSuQmCC";
028    private static String duriSweptArea = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAnUExURQAAAP4A/v41/v5k/v51/v6F/v6T/v6h/v6t/v7E/v7P/v7Z/v7j/s8+NL4AAAABdFJOUwBA5thmAAAAbElEQVQoz2NgGHLgmKHZAVQRVkFBQVFUIUOgkKABsggLSERQBFloIlhIcAK6PkFBByQhiIigAEKEGyokjVcIi0YGRYiQApJQIUSoAEmICSwihOxUTrCQJAOG8yegCPEECgrGoAfYigUMwwIAAJevDkkSlISwAAAAAElFTkSuQmCC";
029    private static String duriWeirs = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAiBAMAAADFd2a2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAhUExURQAAAMDAwMTExMjIyM7OztHR0dXV1d3d3eHh4enp6fDw8MnCp1cAAAABdFJOUwBA5thmAAAASUlEQVQoz2NgIBp4YoiwCU7AEFOUxBBioqEy1lAgCBEUCQUDsNBCQWSwACxk0QEE7R1gYAgRCkAyJXDICWHxI6YQ1ypkwDB4AQCRDzCzcuhQTwAAAABJRU5ErkJggg==";
030
031    private static Bitmap patternBeachSlopeModerate = null;
032    private static Bitmap patternBeachSlopeSteep = null;
033    private static Bitmap patternBeigeStipple = null;
034    private static Bitmap patternFoulGround = null;
035    private static Bitmap patternKelp = null;
036    private static Bitmap patternRigField = null;
037    private static Bitmap patternSweptArea = null;
038    private static Bitmap patternWeirs = null;
039
040    public static Bitmap MakeSymbolPatternFill(String symbolFillIDs, int symbolFillSize)
041    {
042        String[] IDs = symbolFillIDs.split(",");
043        return MakeSymbolPatternFill(IDs, symbolFillSize);
044    }
045
046    public static Bitmap MakeSymbolPatternFill(String[] symbolFillIDs, int symbolFillSize)
047    {
048        Bitmap fill = null;
049        int symCount = symbolFillIDs.length;
050        ImageInfo[] symbols = new ImageInfo[symCount];
051        int width = 0;
052        int height = 0;
053        int top = 0;
054        int bottom = 0;
055        int spacerW = 0;
056        int spacerH = 0;
057        Rect rect = null;
058        SparseArray<String> mods = new SparseArray<String>();
059        SparseArray<String> sa = new SparseArray<String>();
060        sa.put(MilStdAttributes.PixelSize, String.valueOf(symbolFillSize));
061
062        //calculate texture dimensions
063        for(int i = 0; i < symCount; i++)
064        {
065            if(symbolFillIDs[i].charAt(0)=='W')
066                mods.put(MilStdAttributes.OutlineSymbol,"false");
067            else
068                mods.put(MilStdAttributes.OutlineSymbol,"true");
069            symbols[i] = MilStdIconRenderer.getInstance().RenderIcon(symbolFillIDs[i],mods,sa);
070            if(symbols[i] != null)
071            {
072                rect = symbols[i].getImageBounds();
073
074                if(rect.width() > width)
075                    width = rect.width();
076                if(rect.height() > height)
077                    height = rect.height();
078                if(top < symbols[i].getCenterPoint().y)
079                    top = symbols[i].getCenterPoint().y;
080                if(bottom < rect.height() - symbols[i].getCenterPoint().y)
081                    bottom = rect.height() - symbols[i].getCenterPoint().y;
082            }
083        }
084        height = top + bottom;
085        spacerW = width / 3;
086        spacerH = height / 3;
087
088        //create bitmap
089        int bWidth = (width * symCount) + (spacerW * symCount);
090        int bHeight = height + spacerH;
091        if(bWidth > 0 && bHeight > 0)
092        {
093            fill = Bitmap.createBitmap(bWidth,bHeight, Bitmap.Config.ARGB_8888);
094            Canvas canvas = new Canvas(fill);
095            //draw to bitmap
096            int x = spacerW;
097            int y = spacerH;
098            for(int j = 0; j < symCount; j++)
099            {
100                ImageInfo ii = symbols[j];
101                if(ii != null)
102                {
103                    Point center = ii.getCenterPoint();
104                    canvas.drawBitmap(ii.getImage(),x + width/2 - center.x, y + top - center.y,null);
105                    x += spacerW + width;
106                }
107            }
108        }
109        return fill;
110    }
111
112    /*public static Bitmap MakeSymbolPatternFill(ImageInfo[] iia)
113    {
114        Bitmap fill = null;
115        int imageCount = 0;
116        int width = 0;
117        int height = 0;
118        int top = 0;
119        int bottom = 0;
120        int spacerW = 0;
121        int spacerH = 0;
122        Rect rect = null;
123
124        if(iia != null)
125            imageCount = iia.length;
126
127        //calculate texture dimensions
128        for(int i = 0; i < imageCount; i++)
129        {
130            rect = iia[i].getImageBounds();
131            if(rect.width() > width)
132                width = rect.width();
133            if(rect.height() > height)
134                height = rect.height();
135            if(top < iia[i].getCenterPoint().y)
136                top = iia[i].getCenterPoint().y;
137            if(bottom < rect.height() - iia[i].getCenterPoint().y)
138                bottom = rect.height() - iia[i].getCenterPoint().y;
139        }
140        height = top + bottom;
141        spacerW = width / 3;
142        spacerH = height / 3;
143
144        //create bitmap
145        int bWidth = (width * imageCount) + (spacerW * imageCount);
146        int bHeight = height + spacerH;
147        fill = Bitmap.createBitmap(bWidth,bHeight, Bitmap.Config.ARGB_8888);
148        Canvas canvas = new Canvas(fill);
149        //draw to bitmap
150        int x = spacerW;
151        int y = spacerH;
152        for(int j = 0; j < imageCount; j++)
153        {
154            ImageInfo ii = iia[j];
155            Point center = ii.getCenterPoint();
156            canvas.drawBitmap(ii.getImage(),x + width/2 - center.x, y + top - center.y,null);
157            x += spacerW + width;
158        }
159
160        return fill;
161    }//*/
162
163    public static Bitmap MakeMetocPatternFill(String symbolID)
164    {
165        if(symbolID.equals("WO-DBSM-----A--"))//beach slope moderate
166        {
167            if(patternBeachSlopeModerate == null)
168                patternBeachSlopeModerate = LoadBMPFromDataURL(duriBeachSlopeModerate);
169            return patternBeachSlopeModerate;
170        }
171        else if(symbolID.equals("WO-DBST-----A--"))//beach slope steep
172        {
173            if(patternBeachSlopeSteep == null)
174                patternBeachSlopeSteep = LoadBMPFromDataURL(duriBeachSlopeSteep);
175            return patternBeachSlopeSteep;
176        }
177        else if(symbolID.equals("WO-DHCB-----A--"))//beige stipple
178        {
179            if(patternBeigeStipple == null)
180                patternBeigeStipple = LoadBMPFromDataURL(duriBeigeStipple);
181            return patternBeigeStipple;
182        }
183        else if(symbolID.equals("WO-DHHDF----A--"))//Foul Ground
184        {
185            if(patternFoulGround == null)
186                patternFoulGround = LoadBMPFromDataURL(duriFoulGround);
187            return patternFoulGround;
188        }
189        else if(symbolID.equals("WO-DHHDK----A--"))//Kelp
190        {
191            if(patternKelp == null)
192                patternKelp = LoadBMPFromDataURL(duriKelp);
193            return patternKelp;
194        }
195        else if(symbolID.equals("WO-DMOA-----A--"))//OIL/GAS RIG FIELD
196        {
197            if(patternRigField == null)
198                patternRigField = LoadBMPFromDataURL(duriRigField);
199            return patternRigField;
200        }
201        else if(symbolID.equals("WO-DL-SA----A--"))//swept area
202        {
203            if(patternSweptArea == null)
204                patternSweptArea = LoadBMPFromDataURL(duriSweptArea);
205            return patternSweptArea;
206        }
207        else if(symbolID.equals("WOS-HPFF----A--"))//Weirs
208        {
209            if(patternWeirs == null)
210                patternWeirs = LoadBMPFromDataURL(duriWeirs);
211            return patternWeirs;
212        }
213        else
214            return null;
215    }
216
217    private static Bitmap LoadBMPFromDataURL(String durl)
218    {
219        byte[] decodedString = Base64.decode(durl, Base64.DEFAULT);
220        Bitmap bmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
221        return bmp;
222    }
223
224    public static Bitmap MakeHatchPatternFill()
225    {
226        return null;
227    }
228
229    /*private static Bitmap[] fillBMP = null;
230
231    protected static boolean createBitmapShader(TGLight tg,
232                                                ShapeInfo shape,
233                                                Context context)
234    {
235        try
236        {
237            if(fillBMP==null)
238            {
239                fillBMP=new Bitmap[8];
240                for(int j=0;j<8;j++)
241                    fillBMP[j]=null;
242            }
243            BitmapShader fillBMPshader=null;
244            int linetype=tg.get_LineType();
245            int useIndex=-1;
246            switch(linetype)
247            {
248                case TacticalLines.WEIRS:
249                    if(fillBMP[0]==null)
250                        fillBMP[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.weirs);
251                    useIndex=0;
252                    break;
253                case TacticalLines.BEACH_SLOPE_MODERATE:
254                    if(fillBMP[1]==null)
255                        fillBMP[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.beach_slope_moderate);
256                    useIndex=1;
257                    break;
258                case TacticalLines.BEACH_SLOPE_STEEP:
259                    if(fillBMP[2]==null)
260                        fillBMP[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.beach_slope_steep);
261                    useIndex=2;
262                    break;
263                case TacticalLines.KELP:
264                    if(fillBMP[3]==null)
265                        fillBMP[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.kelp);
266                    useIndex=3;
267                    break;
268                case TacticalLines.OIL_RIG_FIELD:
269                    if(fillBMP[4]==null)
270                        fillBMP[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.oil_rig_field);
271                    useIndex=4;
272                    break;
273                case TacticalLines.BEACH:
274                    if(fillBMP[5]==null)
275                        fillBMP[5] = BitmapFactory.decodeResource(context.getResources(), R.drawable.beige_stipple);
276                    useIndex=5;
277                    break;
278                case TacticalLines.FOUL_GROUND:
279                    if(fillBMP[6]==null)
280                        fillBMP[6] = BitmapFactory.decodeResource(context.getResources(), R.drawable.foul_ground);
281                    useIndex=6;
282                    break;
283                case TacticalLines.SWEPT_AREA:
284                    if(fillBMP[7]==null)
285                        fillBMP[7] = BitmapFactory.decodeResource(context.getResources(), R.drawable.swept_area);
286                    useIndex=7;
287                    break;
288                default:    //we do not use pattern fill for these
289                    return false;
290            }
291            if(useIndex >= 0)
292            {
293                fillBMPshader = new BitmapShader(fillBMP[useIndex], Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
294                shape.setShader(fillBMPshader);
295                shape.setFillColor(Color.WHITE);
296                //fillBMP.recycle();
297            }
298        }
299        catch(Exception exc)
300        {
301            ErrorLogger.LogException("clsUtility", "createBitmapShader",
302                    new RendererException("Failed inside createBitmapShader", exc));
303
304        }
305        return true;
306    }//*/
307
308}