tizen 2.4 release
[framework/uifw/cbhm.git] / 2.3-mobile / src / xconverter.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  */
17
18 #include "xconverter.h"
19
20 static char *html_to_entry(AppData *ad, int type_index, const char *str);
21 static char *efl_to_entry(AppData *ad, int type_index, const char *str);
22 static char *text_to_entry(AppData *ad, int type_index, const char *str);
23 static char *image_path_to_entry(AppData *ad, int type_index, const char *str);
24 static char *polaris_to_entry(AppData *ad, int type_index, const char *str);
25
26 //static char *make_close_tag(Eina_List* nodes);
27 static char *do_not_convert(AppData *ad, int type_index, const char *str);
28 static char *html_to_efl(AppData *ad, int type_index, const char *str);
29 static char *efl_to_html(AppData *ad, int type_index, const char *str);
30 static char *text_to_html(AppData *ad, int type_index, const char *str);
31 static char *text_to_efl(AppData *ad, int type_index, const char *str);
32 static char *to_text(AppData *ad, int type_index, const char *str);
33 static char *image_path_to_html(AppData *ad, int type_index, const char *str);
34 static char *image_path_to_efl(AppData *ad, int type_index, const char *str);
35 //static char *image_path_to_text(AppData *ad, int type_index, const char *str);
36 //static char *efl_to_efl(AppData *ad, int type_index, const char *str);
37 //static char *html_to_html(AppData *ad, int type_index, const char *str);
38 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str);
39 static char *html_to_image_path(AppData *ad, int type_index, const char *str);
40 static char *efl_to_image_path(AppData *ad, int type_index, const char *str);
41
42 ENTRY_EMOTICON_S emotion_name_table[ENTRY_EMOTICON_MAX] = {
43         [ENTRY_EMOTICON_HAPPY] = {"emoticon/happy", ":-)"},
44         [ENTRY_EMOTICON_SORRY] = {"emoticon/sorry", ":-("},
45         [ENTRY_EMOTICON_WINK] = {"emoticon/wink", ";-)"},
46         [ENTRY_EMOTICON_TONGUE_DANGLING] = {"emoticon/tongue-dangling", ":-P"},
47         [ENTRY_EMOTICON_SUPRISED] = {"emoticon/surprised", "=-O"},
48         [ENTRY_EMOTICON_KISS] = {"emoticon/kiss", ":-*"},
49         [ENTRY_EMOTICON_ANGRY_SHOUT] = {"emoticon/angry-shout", ":O"},
50         [ENTRY_EMOTICON_SMILE] = {"emoticon/smile", "B-)"},
51         [ENTRY_EMOTICON_OMG] = {"emoticon/omg", ":-["},
52         [ENTRY_EMOTICON_LITTLE_BIT_SORRY] = {"emoticon/little-bit-sorry", ":-\\"},
53         [ENTRY_EMOTICON_VERY_SORRY] = {"emoticon/very-sorry", ":'("},
54         [ENTRY_EMOTICON_GUILTY] = {"emoticon/guilty", ":-X"},
55         [ENTRY_EMOTICON_HAHA] = {"emoticon/haha", ":-D"},
56         [ENTRY_EMOTICON_WORRIED] = {"emoticon/worried", "o_O"},
57         [ENTRY_EMOTICON_LOVE] = {"emoticon/love", "&lt;3"}, //<3
58         [ENTRY_EMOTICON_EVIL] = {"emoticon/evil", "x-("},
59         [ENTRY_EMOTICON_HALF_SMILE] = {"emoticon/half-smile", ":-/"},
60         [ENTRY_EMOTICON_MINIMAL_SMILE] = {"emoticon/minimal-smile", ":-|"},
61 };
62
63 int atom_type_index_get(AppData *ad, Ecore_X_Atom atom)
64 {
65         int i, j;
66         for (i = 0; i < ATOM_INDEX_MAX; i++)
67         {
68                 for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
69                         if (ad->targetAtoms[i].atom[j] == atom)
70                                 return i;
71         }
72         return -1;
73 }
74
75 void init_target_atoms(AppData *ad)
76 {
77         int atom_cnt[ATOM_INDEX_MAX] = {
78                 1, 5, 2, 1, 2, 1
79         };
80         char *targetAtomNames[][5] = {
81                 { "TARGETS" },
82                 { "UTF8_STRING", "STRING", "TEXT", "text/plain;charset=utf-8", "text/plain" },
83                 { "text/html;charset=utf-8", "text/html" },
84                 { "application/x-elementary-markup" },
85                 { "text/uri", "text/uri-list" },
86                 { "polaris-markup" }
87         };
88         text_converter_func converts_to_entry[ATOM_INDEX_MAX] = {
89                 NULL, text_to_entry, html_to_entry, efl_to_entry, image_path_to_entry, polaris_to_entry
90         };
91
92         text_converter_func converts[ATOM_INDEX_MAX][ATOM_INDEX_MAX] = {
93                 {NULL, NULL, NULL, NULL, NULL, NULL},
94                 {NULL, do_not_convert, text_to_html, text_to_efl, NULL, NULL},
95                 {NULL, to_text, do_not_convert, html_to_efl, html_to_image_path, NULL},
96                 {NULL, to_text, efl_to_html, do_not_convert, do_not_convert, NULL},
97                 {NULL, NULL, image_path_to_html, image_path_to_efl, image_path_to_image_path, NULL},
98                 {NULL, to_text, NULL, NULL, NULL, do_not_convert}
99         };
100
101         int i, j;
102         for (i = 0; i < ATOM_INDEX_MAX; i++)
103         {
104                 ad->targetAtoms[i].atom_cnt = atom_cnt[i];
105                 ad->targetAtoms[i].name = MALLOC(sizeof(char *) * atom_cnt[i]);
106                 ad->targetAtoms[i].atom = MALLOC(sizeof(Ecore_X_Atom) * atom_cnt[i]);
107                 for (j = 0; j < atom_cnt[i]; j++)
108                 {
109                         DBG("atomName: %s", targetAtomNames[i][j]);
110                         ad->targetAtoms[i].name[j] = SAFE_STRDUP(targetAtomNames[i][j]);
111                         ad->targetAtoms[i].atom[j] = ecore_x_atom_get(targetAtomNames[i][j]);
112                 }
113                 ad->targetAtoms[i].convert_to_entry = converts_to_entry[i];
114
115                 for (j = 0; j < ATOM_INDEX_MAX; j++)
116                         ad->targetAtoms[i].convert_to_target[j] = converts[i][j];
117                 //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, target_converters[i]);
118                 //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, generic_converter);
119         }
120 }
121
122 void depose_target_atoms(AppData *ad)
123 {
124         int i, j;
125         for (i = 0; i < ATOM_INDEX_MAX; i++)
126         {
127                 for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
128                 {
129                         if (ad->targetAtoms[i].name[j])
130                                 FREE(ad->targetAtoms[i].name[j]);
131                 }
132                 if (ad->targetAtoms[i].name)
133                         FREE(ad->targetAtoms[i].name);
134                 if (ad->targetAtoms[i].atom)
135                         FREE(ad->targetAtoms[i].atom);
136         }
137 }
138
139 static Eina_Bool targets_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
140 {
141         CALLED();
142
143         int count;
144         int i, j;
145         int item_type_index = ATOM_INDEX_TEXT;
146         char *file = NULL;
147
148         if (item)
149         {
150                 item_type_index = item->type_index;
151                 file = item->file;
152         }
153
154         if (!file || item->img_from_web || item->img_from_markup)
155         {
156                 if (item_type_index == ATOM_INDEX_HTML)
157                         ad->targetAtoms[item_type_index].convert_to_target[ATOM_INDEX_IMAGE] = NULL;
158                 else if (item_type_index == ATOM_INDEX_EFL)
159                         ad->targetAtoms[item_type_index].convert_to_target[ATOM_INDEX_IMAGE] = NULL;
160         }
161
162         for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
163         {
164                 if (ad->targetAtoms[item_type_index].convert_to_target[i])
165                         count += ad->targetAtoms[i].atom_cnt;
166         }
167
168         *data_ret = MALLOC(sizeof(Ecore_X_Atom) * count);
169         DBG("item_type: %d, target Atom cnt: %d", item_type_index, count);
170         if (!*data_ret)
171                 return EINA_FALSE;
172
173         for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
174         {
175                 if (ad->targetAtoms[item_type_index].convert_to_target[i])
176                 {
177                         for(j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
178                         {
179                                 ((Ecore_X_Atom *)*data_ret)[count++] = ad->targetAtoms[i].atom[j];
180                                 DBG("send target atom: %s", ad->targetAtoms[i].name[j]);
181                         }
182                 }
183         }
184
185         if (!file)
186         {
187                 if (item_type_index == ATOM_INDEX_HTML)
188                         ad->targetAtoms[item_type_index].convert_to_target[ATOM_INDEX_IMAGE] = html_to_image_path;
189                 else if (item_type_index == ATOM_INDEX_EFL)
190                         ad->targetAtoms[item_type_index].convert_to_target[ATOM_INDEX_IMAGE] = efl_to_image_path;
191         }
192
193         if (size_ret) *size_ret = count;
194         if (ttype) *ttype = ECORE_X_ATOM_ATOM;
195         if (tsize) *tsize = 32;
196         return EINA_TRUE;
197 }
198
199 Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
200 {
201         CALLED();
202
203         if (ad->targetAtoms[ATOM_INDEX_TARGET].atom[0] == reqAtom)
204                 return targets_converter(ad, reqAtom, item, data_ret, size_ret, ttype, tsize);
205
206         int req_index = atom_type_index_get(ad, reqAtom);
207         int item_type_index = ATOM_INDEX_TEXT;
208         void *item_data = "";
209
210         if (req_index < 0) return EINA_FALSE;
211
212         if (item)
213         {
214                 item_type_index = item->type_index;
215                 item_data = item->data;
216         }
217
218         if (ad->targetAtoms[item_type_index].convert_to_target[req_index])
219         {
220                 *data_ret = ad->targetAtoms[item_type_index].convert_to_target[req_index](ad, item_type_index, item_data);
221                 if (!*data_ret)
222                         return EINA_FALSE;
223                 if (size_ret) *size_ret = SAFE_STRLEN(*data_ret);
224                 if (ttype) *ttype = ad->targetAtoms[item_type_index].atom[0];
225                 if (tsize) *tsize = 8;
226                 return EINA_TRUE;
227         }
228
229         return EINA_FALSE;
230 }
231
232 /* For convert EFL to HTML */
233
234 #define TAGPOS_START    0x00000001
235 #define TAGPOS_END      0x00000002
236 #define TAGPOS_ALONE    0x00000003
237
238 /* TEXTBLOCK tag using stack but close tag word has no mean maybe bug...
239  * TEXTBLOCK <b>bold<font>font</b>bold</font>
240  * HTML <b>bold<font>font bold</b>font</font> */
241
242 typedef struct _TagTable {
243         char *src;
244         char *dst;
245 }TagTable;
246
247 TagTable _EFLtoHTMLConvertTable[] = {
248         {"font", "font"},
249         {"underline", "del"},
250         {"strikethrough", "ins"},
251         {"br", "br"},
252         {"br/", "br"},
253         {"ps", "br"},
254         {"b", "b"},
255         {"item", "img"}
256 };
257
258 TagTable _HTMLtoEFLConvertTable[] = {
259         {"font", ""},
260         {"del", "underline"},
261         {"u", "underline"},
262         {"ins", "strikethrough"},
263         {"s", "strikethrough"},
264         {"br", "br"},
265         {"b", "b"},
266         {"strong", "b"},
267         {"img", "item"}
268 };
269
270
271 typedef struct _TagNode TagNode, *PTagNode;
272 struct _TagNode {
273         char *tag;  //EINA_STRINGSHARE if NULL just str
274         char *tag_str;
275         char *str;
276         const char *pos_in_ori_str;
277         PTagNode matchTag;
278         void *tagData;
279         unsigned char tagPosType;
280 };
281
282 typedef struct _FontTagData FontTagData, *PFontTagData;
283 struct _FontTagData {
284         char *name;
285         char *color;
286         char *size;
287         char *bg_color;
288 };
289
290
291 typedef struct _ItemTagData ItemTagData, *PItemTagData;
292 struct _ItemTagData {
293         char *href;
294         char *width;
295         char *height;
296 };
297
298 #define SAFEFREE(ptr) \
299         do\
300 {\
301         if (ptr)\
302         FREE(ptr);\
303         ptr = NULL;\
304 } while(0);\
305
306 #define freeAndAssign(dst, value) \
307         do\
308 {\
309         if (value)\
310         {\
311                 SAFEFREE(dst);\
312                 dst = value;\
313         }\
314 } while(0);
315
316 static PTagNode _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str);
317 static PTagNode _get_start_node(const char *str);
318 static PTagNode _get_next_node(PTagNode prev);
319 static void _delete_node(PTagNode node);
320 static void _link_match_tags(Eina_List *nodes);
321 static char *_get_tag_value(const char *tag_str, const char *tag_name);
322 static char *_convert_to_html(Eina_List* nodes);
323 static void _set_EFL_tag_data(Eina_List* nodes);
324 static char *_convert_to_edje(Eina_List* nodes);
325 static void _set_HTML_tag_data(Eina_List* nodes);
326 static void cleanup_tag_list(Eina_List *nodeList);
327 static PFontTagData _set_EFL_font_data(PFontTagData data, const char *tag_str);
328 static PItemTagData _set_EFL_item_data(PItemTagData data, const char *tag_str);
329 static PFontTagData _set_HTML_font_data(PFontTagData data, const char *tag_str);
330 static PItemTagData _set_HTML_img_data(PItemTagData data, const char *tag_str);
331
332 static void _dumpNode(Eina_List* nodes);
333
334 static PTagNode
335 _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str)
336 {
337         PTagNode newNode = CALLOC(1, sizeof(TagNode));
338         if (tag)
339                 eina_str_tolower(&tag);
340         newNode->tag = tag;
341         newNode->tag_str = tag_str;
342         newNode->str = str;
343         newNode->pos_in_ori_str = pos_in_ori_str;
344         return newNode;
345 }
346
347 static PTagNode
348 _get_start_node(const char *str)
349 {
350         char *startStr = NULL;
351         if (!str || str[0] == '\0')
352                 return NULL;
353
354         if (str[0] != '<')
355         {
356                 char *tagStart = SAFE_STRCHR(str, '<');
357                 if (!tagStart)
358                         startStr = SAFE_STRDUP(str);
359                 else
360                 {
361                         int strLength = tagStart - str;
362                         startStr = MALLOC(sizeof(char) * (strLength + 1));
363                         SAFE_STRNCPY(startStr, str, strLength);
364                         startStr[strLength] = '\0';
365                 }
366         }
367
368         return _new_tag_node(NULL, NULL, startStr, str);
369 }
370
371 static PTagNode
372 _get_next_node(PTagNode prev)
373 {
374         PTagNode retTag = NULL;
375         char *tagStart;
376         char *tagEnd;
377         char *tagNameEnd = NULL;
378         char *nextTagStart;
379
380         if (prev->tag == NULL)
381                 tagStart = SAFE_STRCHR(prev->pos_in_ori_str, '<');
382         else
383                 tagStart = SAFE_STRCHR(prev->pos_in_ori_str + 1, '<');
384
385         if (!tagStart)
386                 return retTag;
387
388         tagEnd = SAFE_STRCHR(tagStart, '>');
389         nextTagStart = SAFE_STRCHR(tagStart + 1, '<');
390
391         if (!tagEnd || (nextTagStart && (nextTagStart < tagEnd)))
392                 return _get_start_node(tagStart + 1);
393
394         int spCnt = 5;
395         char *spArray[spCnt];
396         spArray[0] = SAFE_STRCHR(tagStart, '=');
397         spArray[1] = SAFE_STRCHR(tagStart, '_');
398         spArray[2] = SAFE_STRCHR(tagStart, ' ');
399         spArray[3] = SAFE_STRCHR(tagStart, '\t');
400         spArray[4] = SAFE_STRCHR(tagStart, '\n');
401         tagNameEnd = tagEnd;
402
403         int i;
404         for (i = 0; i < spCnt; i++)
405         {
406                 if (spArray[i] && spArray[i] < tagNameEnd)
407                         tagNameEnd = spArray[i];
408         }
409
410         int tagLength = tagNameEnd - tagStart - 1;
411         char *tagName = NULL;
412         if (!SAFE_STRNCMP(&tagStart[1], "/item", tagLength))
413                 tagName = SAFE_STRDUP("");
414         else
415                 tagName = SAFE_STRNDUP(&tagStart[1], tagLength);
416
417         int tagStrLength = 0;
418         char *tagStr = NULL;
419         if (tagName)
420         {
421                 tagStrLength = tagEnd - tagStart + 1;
422                 tagStr = SAFE_STRNDUP(tagStart, tagStrLength);
423         }
424
425         unsigned int strLength = nextTagStart ? (unsigned int)(nextTagStart - tagEnd - 1) : SAFE_STRLEN(&tagEnd[1]);
426         char *str = SAFE_STRNDUP(&tagEnd[1], strLength);
427
428         retTag = _new_tag_node(tagName, tagStr, str, tagStart);
429         return retTag;
430 }
431
432
433 static void
434 _delete_node(PTagNode node)
435 {
436         if (node)
437         {
438                 SAFEFREE(node->tag_str);
439                 SAFEFREE(node->str);
440
441                 if (node->tagData)
442                 {
443                         if (node->tag)
444                         {
445                                 if (!SAFE_STRCMP("font", node->tag))
446                                 {
447                                         PFontTagData data = node->tagData;
448                                         SAFEFREE(data->name);
449                                         SAFEFREE(data->color);
450                                         SAFEFREE(data->size);
451                                         SAFEFREE(data->bg_color);
452                                 }
453                                 if (!SAFE_STRCMP("item", node->tag))
454                                 {
455                                         PItemTagData data = node->tagData;
456                                         SAFEFREE(data->href);
457                                         SAFEFREE(data->width);
458                                         SAFEFREE(data->height);
459                                 }
460                         }
461                         SAFEFREE(node->tagData);
462                 }
463                 SAFEFREE(node->tag);
464                 SAFEFREE(node);
465         }
466 }
467
468 static void
469 _link_match_tags(Eina_List *nodes)
470 {
471         Eina_List *stack = NULL;
472
473         PTagNode trail, popData;
474         Eina_List *l, *r;
475
476         EINA_LIST_FOREACH(nodes, l, trail)
477         {
478                 if (!trail || !trail->tag || trail->tag[0] == '\0') continue;
479
480                 if (!SAFE_STRCMP("br", trail->tag) || !SAFE_STRCMP("br/", trail->tag))
481                 {
482                         trail->tagPosType = TAGPOS_ALONE;
483                         continue;
484                 }
485                 else if (!SAFE_STRCMP("item", trail->tag) || !SAFE_STRCMP("img", trail->tag))
486                 {
487                         trail->tagPosType = TAGPOS_ALONE;
488                         continue;
489                 }
490
491                 if (trail->tag[0] != '/') // PUSH
492                 {
493                         stack = eina_list_append(stack, trail);
494                         /*             eina_array_push(stack, trail);
495                                                    DBG("stack: %d, tag %s", eina_array_count_get(stack), trail->tag);*/
496                         DBG("stack: %d, tag %s", eina_list_count(stack), trail->tag);
497                 }
498                 else // POP
499                 {
500                         if (!eina_list_count(stack))
501                         {
502                                 WRN("tag not matched %s", trail->tag);
503                                 continue;
504                         }
505
506                         EINA_LIST_REVERSE_FOREACH(stack, r, popData)
507                         {
508                                 if (!popData || !popData->tag || popData->tag[0] == '\0') continue;
509
510                                 if (!SAFE_STRCMP(popData->tag, &trail->tag[1]))
511                                 {
512                                         popData->tagPosType = TAGPOS_START;
513                                         trail->tagPosType = TAGPOS_END;
514                                         popData->matchTag = trail;
515                                         trail->matchTag = popData;
516                                         stack = eina_list_remove_list(stack, r);
517                                         break;
518                                 }
519                         }
520                         /*             popData = eina_array_pop(stack);
521
522                                                    popData->tagPosType = TAGPOS_START;
523                                                    trail->tagPosType = TAGPOS_END;
524                                                    popData->matchTag = trail;
525                                                    trail->matchTag = popData;
526                                                    DBG("pop stack: %d, tag %s", eina_array_count_get(stack), trail->tag);
527                          */
528                 }
529         }
530
531         /*   if (eina_array_count_get(stack))
532                  DBG("stack state: %d, tag %s", eina_array_count_get(stack), trail->tag);*/
533
534         /* Make Dummy close tag */
535         /*   while ((popData = eina_array_pop(stack)))  */
536
537         EINA_LIST_REVERSE_FOREACH(stack, r, popData)
538         {
539                 if (!popData) continue;
540
541                 PTagNode newData;
542                 int tagLength = SAFE_STRLEN(popData->tag);
543                 char *tagName = MALLOC(sizeof(char) * (tagLength + 2));
544                 if (!tagName) break;
545
546                 tagName[0] = '/';
547                 tagName[1] = '\0';
548                 SAFE_STRCAT(tagName, popData->tag);
549
550                 newData = _new_tag_node(tagName, NULL, NULL, NULL);
551                 popData->tagPosType = TAGPOS_START;
552                 newData->tagPosType = TAGPOS_END;
553                 popData->matchTag = newData;
554                 newData->matchTag = popData;
555                 nodes = eina_list_append(nodes, newData);
556                 /*        DBG("stack: %d, tag %s", eina_array_count_get(stack), popData->tag);*/
557         }
558         /*   DBG("stack_top: %d", eina_array_count_get(stack));
559                  eina_array_free(stack);*/
560         eina_list_free(stack);
561 }
562
563 static char *
564 _get_tag_value(const char *tag_str, const char *tag_name)
565 {
566         if (!tag_name || !tag_str)
567                 return NULL;
568
569         char *tag;
570         if ((tag = SAFE_STRSTR(tag_str, tag_name)))
571         {
572                 if (tag[SAFE_STRLEN(tag_name)] == '_')
573                         return NULL;
574                 char *value = SAFE_STRCHR(tag, '=');
575                 if (value)
576                 {
577                         do
578                         {
579                                 value++;
580                         } while (!isalnum(*value) && *value != '#');
581
582                         int spCnt = 6;
583                         char *spArray[spCnt];
584                         spArray[0] = SAFE_STRCHR(value, ' ');
585                         spArray[1] = SAFE_STRCHR(value, '>');
586                         spArray[2] = SAFE_STRCHR(value, '\"');
587                         spArray[3] = SAFE_STRCHR(value, '\'');
588                         spArray[4] = SAFE_STRCHR(value, '\t');
589                         spArray[5] = SAFE_STRCHR(value, '\n');
590                         char *valueEnd = SAFE_STRCHR(value, '\0');
591
592                         int i;
593                         int start = 0;
594                         if ((!SAFE_STRNCMP(tag_str, "<item", 5) && !SAFE_STRCMP(tag_name, "href")) // EFL img tag
595                || (!SAFE_STRNCMP(tag_str, "<img", 4) && !SAFE_STRCMP(tag_name, "src"))) // HTML img tag
596                start = 1;
597
598                         for (i = start; i < spCnt; i++)
599                         {
600                                 if (spArray[i] && spArray[i] < valueEnd)
601                                         valueEnd = spArray[i];
602                         }
603
604                         int valueLength = valueEnd - value;
605                         return SAFE_STRNDUP(value, valueLength);
606                 }
607         }
608         return NULL;
609 }
610
611 static PFontTagData
612 _set_EFL_font_data(PFontTagData data, const char *tag_str)
613 {
614         char *value;
615
616         if (!data)
617                 data = CALLOC(1, sizeof(FontTagData));
618         value = _get_tag_value(tag_str, "font_size");
619         freeAndAssign(data->size, value);
620         value = _get_tag_value(tag_str, "color");
621         freeAndAssign(data->color, value);
622         value = _get_tag_value(tag_str, "bgcolor");
623         freeAndAssign(data->bg_color, value);
624         value = _get_tag_value(tag_str, "font");
625         freeAndAssign(data->name, value);
626
627         return data;
628 }
629
630 static PItemTagData
631 _set_EFL_item_data(PItemTagData data, const char *tag_str)
632 {
633         char *value;
634
635         if (!data)
636                 data = CALLOC(1, sizeof(ItemTagData));
637         value = _get_tag_value(tag_str, "href");
638         if (value)
639         {
640                 char *path = SAFE_STRSTR(value, "file://");
641                 if (path)
642                 {
643                         char *modify = MALLOC(sizeof(char) * (SAFE_STRLEN(value) + 1));
644                         SAFE_STRNCPY(modify, "file://", 8);
645                         path += 7;
646                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
647                         {
648                                 path++;
649                         }
650                         SAFE_STRCAT(modify, path);
651                         data->href = modify;
652                         DBG("image href ---%s---", data->href);
653                         FREE(value);
654                 }
655                 else
656                         freeAndAssign(data->href, value);
657         }
658
659         value = _get_tag_value(tag_str, "absize");
660         if (value)
661         {
662                 char *xpos = SAFE_STRCHR(value, 'x');
663                 if (xpos)
664                 {
665                         int absizeLen = SAFE_STRLEN(value);
666                         freeAndAssign(data->width, SAFE_STRNDUP(value, xpos - value));
667                         freeAndAssign(data->height, SAFE_STRNDUP(xpos + 1, absizeLen - (xpos - value) - 1));
668                         DBG("image width: -%s-, height: -%s-", data->width, data->height);
669                 }
670                 FREE(value);
671         }
672         return data;
673 }
674
675 static void
676 _set_EFL_tag_data(Eina_List* nodes)
677 {
678         PTagNode trail;
679         Eina_List *l;
680
681         EINA_LIST_FOREACH(nodes, l, trail)
682         {
683                 if (!trail || !trail->tag || trail->tag[0] == '\0') continue;
684
685                 if (!SAFE_STRCMP("font", trail->tag) || !SAFE_STRCMP("color", trail->tag))
686                         trail->tagData = _set_EFL_font_data(trail->tagData, trail->tag_str);
687                 else if (!SAFE_STRCMP("item", trail->tag))
688                         trail->tagData = _set_EFL_item_data(trail->tagData, trail->tag_str);
689         }
690 }
691
692 static PFontTagData
693 _set_HTML_font_data(PFontTagData data, const char *tag_str)
694 {
695         char *value;
696
697         if (!data)
698                 data = CALLOC(1, sizeof(FontTagData));
699         value = _get_tag_value(tag_str, "size");
700         freeAndAssign(data->size, value);
701         value = _get_tag_value(tag_str, "color");
702         freeAndAssign(data->color, value);
703         value = _get_tag_value(tag_str, "bgcolor");
704         freeAndAssign(data->bg_color, value);
705         value = _get_tag_value(tag_str, "face");
706         freeAndAssign(data->name, value);
707
708         return data;
709 }
710
711 static PItemTagData
712 _set_HTML_img_data(PItemTagData data, const char *tag_str)
713 {
714         char *value;
715
716         if (!data)
717                 data = CALLOC(1, sizeof(ItemTagData));
718         value = _get_tag_value(tag_str, "src");
719         if (value)
720         {
721                 char *path = SAFE_STRSTR(value, "file://");
722                 if (path)
723                 {
724                         char *modify = MALLOC(sizeof(char) * (SAFE_STRLEN(value) + 1));
725                         SAFE_STRNCPY(modify, "file://", 8);
726                         path += 7;
727                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
728                         {
729                                 path++;
730                         }
731                         SAFE_STRCAT(modify, path);
732                         data->href = modify;
733                         DBG("image src ---%s---", data->href);
734                         FREE(value);
735                 }
736                 else
737                         freeAndAssign(data->href, value);
738         }
739
740         value = _get_tag_value(tag_str, "width");
741         freeAndAssign(data->width, value);
742         value = _get_tag_value(tag_str, "height");
743         freeAndAssign(data->height, value);
744         return data;
745 }
746
747 static void
748 _set_HTML_tag_data(Eina_List* nodes)
749 {
750         PTagNode trail;
751         Eina_List *l;
752
753         EINA_LIST_FOREACH(nodes, l, trail)
754         {
755                 if (!trail || !trail->tag || trail->tag[0] == '\0') continue;
756
757                 if (!SAFE_STRCMP("font", trail->tag) || !SAFE_STRCMP("color", trail->tag))
758                         trail->tagData = _set_HTML_font_data(trail->tagData, trail->tag_str);
759                 else if (!SAFE_STRCMP("img", trail->tag))
760                         trail->tagData = _set_HTML_img_data(trail->tagData, trail->tag_str);
761         }
762 }
763
764 static void
765 _dumpNode(Eina_List* nodes)
766 {
767         PTagNode trail;
768         Eina_List *l;
769
770         EINA_LIST_FOREACH(nodes, l, trail)
771         {
772                 if (!trail) continue;
773
774                 DBG("tag: %s, tag_str: %s, str: %s, tagPosType: %d",
775                                 trail->tag, trail->tag_str, trail->str, trail->tagPosType);
776                 DBG("matchTag: %x", (unsigned int)trail->matchTag);
777                 if (trail->matchTag)
778                         DBG("matchTag->tag_str: %s", trail->matchTag->tag_str);
779                 if (trail->tagData)
780                 {
781                         if (!SAFE_STRCMP(trail->tag, "font"))
782                         {
783                                 PFontTagData data = trail->tagData;
784                                 DBG(" tagData->name: %s, tagData->color: %s, tagData->size: %s, tagData->bg_color: %s",
785                                                 data->name, data->color, data->size, data->bg_color);
786                         }
787                         else if (!SAFE_STRCMP(trail->tag, "item") || !SAFE_STRCMP(trail->tag, "img"))
788                         {
789                                 PItemTagData data = trail->tagData;
790                                 DBG(" tagData->href: %s, tagData->width: %s, tagData->height: %s",
791                                                 data->href, data->width, data->height);
792                         }
793                         else
794                                 WRN("ERROR!!!! not need tagData");
795                 }
796         }
797 }
798
799 static char *
800 _convert_to_html(Eina_List* nodes)
801 {
802         PTagNode trail;
803         Eina_List *l;
804
805         Eina_Strbuf *html = eina_strbuf_new();
806
807         int tableCnt = sizeof(_EFLtoHTMLConvertTable) / sizeof(TagTable);
808
809         EINA_LIST_FOREACH(nodes, l, trail)
810         {
811                 if (!trail) continue;
812
813                 if (trail->tag)
814                 {
815                         char *tagName = trail->tagPosType == TAGPOS_END ?
816                                 trail->matchTag->tag : trail->tag;
817                         int j;
818                         for(j = 0; j < tableCnt; j++)
819                         {
820                                 if (!SAFE_STRCMP(_EFLtoHTMLConvertTable[j].src, tagName))
821                                 {
822                                         switch(trail->tagPosType)
823                                         {
824                                                 case TAGPOS_END:
825                                                         eina_strbuf_append(html, "</");
826                                                         break;
827                                                 default:
828                                                         eina_strbuf_append(html, "<");
829                                                         break;
830                                         }
831
832                                         eina_strbuf_append(html, _EFLtoHTMLConvertTable[j].dst);
833                                         if (trail->tagPosType != TAGPOS_END)
834                                         {
835                                                 if (!SAFE_STRCMP(_EFLtoHTMLConvertTable[j].src, "font"))
836                                                 {
837                                                         PFontTagData data = trail->tagData;
838                                                         if (data->name)
839                                                         {
840                                                         }
841                                                         if (data->color)
842                                                         {
843                                                                 char *color = SAFE_STRDUP(data->color);
844                                                                 if (color && color[0] == '#' && SAFE_STRLEN(color) == 9)
845                                                                 {
846                                                                         color[7] = '\0';
847                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", color);
848                                                                 }
849                                                                 else
850                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", data->color);
851                                                                 if (color)
852                                                                         FREE(color);
853                                                         }
854                                                         if (data->size)
855                                                                 eina_strbuf_append_printf(html, " size=\"%s\"", data->size);
856                                                         if (data->bg_color)
857                                                         {
858                                                         }
859                                                 }
860                                                 else if (!SAFE_STRCMP(_EFLtoHTMLConvertTable[j].src, "item"))
861                                                 {
862                                                         PItemTagData data = trail->tagData;
863                                                         if (data->href)
864                                                                 eina_strbuf_append_printf(html, " src=\"%s\"", data->href);
865                                                         if (data->width)
866                                                                 eina_strbuf_append_printf(html, " width=\"%s\"", data->width);
867                                                         if (data->height)
868                                                                 eina_strbuf_append_printf(html, " height=\"%s\"", data->height);
869                                                 }
870                                         }
871                                         switch(trail->tagPosType)
872                                         {
873                                                 /* closed tag does not need in HTML
874                                                    case TAGPOS_ALONE:
875                                                    eina_strbuf_append(html, " />");
876                                                    break;*/
877                                                 default:
878                                                         eina_strbuf_append(html, ">");
879                                                         break;
880                                         }
881                                         break;
882                                 }
883                         }
884                 }
885                 if (trail->str)
886                         eina_strbuf_append(html, trail->str);
887         }
888
889         eina_strbuf_replace_all(html, "  ", " &nbsp;");
890         char *ret = eina_strbuf_string_steal(html);
891         eina_strbuf_free(html);
892         return ret;
893 }
894
895 #define IMAGE_DEFAULT_WIDTH "240"
896 #define IMAGE_DEFAULT_HEIGHT "180"
897
898
899 static char *
900 _convert_to_edje(Eina_List* nodes)
901 {
902         PTagNode trail;
903         Eina_List *l;
904
905         Eina_Strbuf *edje = eina_strbuf_new();
906
907         int tableCnt = sizeof(_HTMLtoEFLConvertTable) / sizeof(TagTable);
908
909         EINA_LIST_FOREACH(nodes, l, trail)
910         {
911                 if (!trail) continue;
912
913                 if (trail->tag)
914                 {
915                         char *tagName = trail->tagPosType == TAGPOS_END ?
916                                 trail->matchTag->tag : trail->tag;
917                         int j;
918                         for(j = 0; j < tableCnt; j++)
919                         {
920                                 if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, tagName))
921                                 {
922                                         if (_HTMLtoEFLConvertTable[j].dst[0] != '\0')
923                                         {
924                                                 switch(trail->tagPosType)
925                                                 {
926                                                         case TAGPOS_END:
927                                                                 eina_strbuf_append(edje, "</");
928                                                                 break;
929                                                         default:
930                                                                 eina_strbuf_append(edje, "<");
931                                                                 break;
932                                                 }
933
934                                                 eina_strbuf_append(edje, _HTMLtoEFLConvertTable[j].dst);
935                                         }
936                                         if (trail->tagPosType != TAGPOS_END)
937                                         {
938                                                 if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, "font"))
939                                                 {
940                                                         PFontTagData data = trail->tagData;
941                                                         if (data->name)
942                                                         {
943                                                         }
944                                                         if (data->color)
945                                                         {
946                                                                 if (data->color[0] == '#' && SAFE_STRLEN(data->color) == 7)
947                                                                         eina_strbuf_append_printf(edje, "<color=%sff>", data->color);
948                                                                 else
949                                                                         eina_strbuf_append_printf(edje, "<color=%s>", data->color);
950
951                                                         }
952                                                         if (data->size)
953                                                                 eina_strbuf_append_printf(edje, "<font_size=%s>", data->size);
954                                                         if (data->bg_color)
955                                                         {
956                                                         }
957                                                         break;
958                                                 }
959                                                 else if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, "img"))
960                                                 {
961                                                         PItemTagData data = trail->tagData;
962                                                         char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT;
963                                                         if (data->width)
964                                                                 width = data->width;
965                                                         if (data->height)
966                                                                 height = data->height;
967                                                         eina_strbuf_append_printf(edje, " absize=%sx%s", width, height);
968                                                         if (data->href)
969                                                                 eina_strbuf_append_printf(edje, " href=%s></item>", data->href);
970                                                         break;
971                                                 }
972                                         }
973                                         else
974                                         {
975                                                 if (_HTMLtoEFLConvertTable[j].dst[0] == '\0')
976                                                 {
977                                                         if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, "font"))
978                                                         {
979                                                                 if (trail->matchTag->tagData)
980                                                                 {
981                                                                         PFontTagData data = trail->matchTag->tagData;
982                                                                         if (data->name)
983                                                                         {
984                                                                         }
985                                                                         if (data->color)
986                                                                                 eina_strbuf_append_printf(edje, "</color>");
987                                                                         if (data->size)
988                                                                                 eina_strbuf_append_printf(edje, "</font>");
989                                                                         if (data->bg_color)
990                                                                         {
991                                                                         }
992                                                                         break;
993                                                                 }
994                                                         }
995                                                 }
996                                         }
997                                         switch(trail->tagPosType)
998                                         {
999                                                 /* not support in efl
1000                                                    case TAGPOS_ALONE:
1001                                                    eina_strbuf_append(edje, " />");
1002                                                    break;
1003                                                  */
1004                                                 default:
1005                                                         eina_strbuf_append(edje, ">");
1006                                                         break;
1007                                         }
1008                                         break;
1009                                 }
1010                         }/* for(j = 0; j < tableCnt; j++) end */
1011                 }
1012                 if (trail->str)
1013                         eina_strbuf_append(edje, trail->str);
1014         }
1015
1016         eina_strbuf_replace_all(edje, "&nbsp;", " ");
1017         char *ret = eina_strbuf_string_steal(edje);
1018         eina_strbuf_free(edje);
1019         return ret;
1020 }
1021
1022 char *string_for_entry_get(AppData *ad, int type_index, const char *str)
1023 {
1024         DBG("type_index: %d str: %s ", type_index, str);
1025         if (ad->targetAtoms[type_index].convert_to_entry)
1026                 return ad->targetAtoms[type_index].convert_to_entry(ad, type_index, str);
1027         return NULL;
1028 }
1029
1030 char *string_for_image_path_get(AppData *ad, int type_index, const char *str)
1031 {
1032         DBG("type_index: %d str: %s ", type_index, str);
1033         char *image_path = NULL;
1034
1035         if (type_index == ATOM_INDEX_HTML)
1036                 image_path = html_to_image_path(ad, type_index, str);
1037         else if (type_index == ATOM_INDEX_EFL)
1038                 image_path = efl_to_image_path(ad, type_index, str);
1039
1040         return image_path;
1041 }
1042 /*
1043 static char *make_close_tag(Eina_List* nodes)
1044 {
1045         CALLED();
1046         PTagNode trail;
1047         Eina_List *l;
1048
1049         Eina_Strbuf *tag_str = eina_strbuf_new();
1050
1051         EINA_LIST_FOREACH(nodes, l, trail)
1052         {
1053                 if (trail->tag)
1054                 {
1055                         if (trail->tag_str)
1056                                 eina_strbuf_append(tag_str, trail->tag_str);
1057                         else
1058                         {
1059                                 eina_strbuf_append(tag_str, "<");
1060                                 eina_strbuf_append(tag_str, trail->tag);
1061                                 eina_strbuf_append(tag_str, ">");
1062                         }
1063                 }
1064                 if (trail->str)
1065                         eina_strbuf_append(tag_str, trail->str);
1066         }
1067
1068         char *ret = eina_strbuf_string_steal(tag_str);
1069         eina_strbuf_free(tag_str);
1070         return ret;
1071 }
1072 */
1073 static char *do_not_convert(AppData *ad, int type_index, const char *str)
1074 {
1075         DBG("str: %s", str);
1076         if (type_index != ATOM_INDEX_HTML)
1077         {
1078                 char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1079                 return emoticon_text;
1080         }
1081         return SAFE_STRDUP(str);
1082 }
1083 /*
1084    static char *efl_to_efl(AppData *ad, int type_index, const char *str)
1085    {
1086    CALLED();
1087    return NULL;
1088    }
1089
1090    static char *html_to_html(AppData *ad, int type_index, const char *str)
1091    {
1092    CALLED();
1093    return NULL;
1094    }
1095  */
1096
1097 #define IMAGE_DEFAULT_WIDTH "240"
1098 #define IMAGE_DEFAULT_HEIGHT "180"
1099 static char *make_image_path_tag(int type_index, const char *str)
1100 {
1101         char *img_tag_str = "file://%s";
1102         char *efl_img_tag = "<item absize="IMAGE_DEFAULT_WIDTH"x"IMAGE_DEFAULT_HEIGHT" href=file://%s>";
1103         char *html_img_tag = "<img src=\"file://%s\">";
1104
1105         switch (type_index)
1106         {
1107                 case ATOM_INDEX_HTML:
1108                         img_tag_str = html_img_tag;
1109                         break;
1110                 case ATOM_INDEX_EFL:
1111                         img_tag_str = efl_img_tag;
1112                         break;
1113                 case ATOM_INDEX_TEXT:
1114                 case ATOM_INDEX_IMAGE:
1115                         break;
1116                 default:
1117                         ERR("wrong type_index: %d", type_index);
1118                         return NULL;
1119         }
1120
1121         size_t len = snprintf(NULL, 0, img_tag_str, str) + 1;
1122         char *ret = MALLOC(sizeof(char) * len);
1123         if (ret)
1124                 snprintf(ret, len, img_tag_str, str);
1125         return ret;
1126 }
1127
1128 /*
1129 static char *image_path_to_text(AppData *ad, int type_index, const char *str)
1130 {
1131         DBG("str: %s", str);
1132         return make_image_path_tag(ATOM_INDEX_TEXT, str);
1133 }
1134 */
1135
1136 static char *image_path_to_html(AppData *ad, int type_index, const char *str)
1137 {
1138         DBG("str: %s", str);
1139         return make_image_path_tag(ATOM_INDEX_HTML, str);
1140 }
1141
1142 static char *image_path_to_efl(AppData *ad, int type_index, const char *str)
1143 {
1144         DBG("str: %s", str);
1145         return make_image_path_tag(ATOM_INDEX_EFL, str);
1146 }
1147
1148 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str)
1149 {
1150         DBG("str: %s", str);
1151         return make_image_path_tag(ATOM_INDEX_IMAGE, str);
1152 }
1153
1154 static char *html_to_image_path(AppData *ad, int type_index, const char *str)
1155 {
1156         DBG("str: %s", str);
1157         Eina_Strbuf *sbuf = eina_strbuf_new();
1158         Eina_Bool image_path_exists = EINA_FALSE;
1159         int len = SAFE_STRLEN(str);
1160         char *p = (char *)str;
1161         char *s;
1162         char *image_path = NULL;
1163
1164         if (type_index == ATOM_INDEX_HTML)
1165         {
1166                 for (s = p; (p - s) <= len; p++)
1167                 {
1168                         if (*p == '<')
1169                         {
1170                                 if (!SAFE_STRNCMP((p + 1), "img", 3))
1171                                 {
1172                                         for (p += 4; *p != '"'; p++);
1173                                         if (!SAFE_STRNCMP((p + 1), "http:/", 6) || !SAFE_STRNCMP((p + 1), "file:/", 6))
1174                                         {
1175                                                 if (!SAFE_STRNCMP((p + 1), "http:/", 6))
1176                                                         ad->clipdrawer->http_path = EINA_TRUE;
1177                                                 else
1178                                                         ad->clipdrawer->http_path = EINA_FALSE;
1179
1180                                                 p += 7;
1181                                                 s = p;
1182                                                 for (; *p != '"'; p++);
1183                                                 eina_strbuf_append_length(sbuf, s, p - s);
1184                                                 image_path_exists = EINA_TRUE;
1185                                                 break;
1186                                         }
1187                                         else if ((*(p + 1) == '/'))
1188                                         {
1189                                                 p++;
1190                                                 s = p;
1191                                                 for (; *p != '"'; p++);
1192                                                 eina_strbuf_append_length(sbuf, s, p - s);
1193                                                 image_path_exists = EINA_TRUE;
1194                                                 ad->clipdrawer->http_path = EINA_FALSE;
1195                                                 break;
1196                                         }
1197                                 }
1198                         }
1199                 }
1200         }
1201
1202         if (image_path_exists)
1203         {
1204                 //Replace the space Unicode character(%20).
1205                 eina_strbuf_replace_all(sbuf, "%20", " ");
1206                 image_path = eina_strbuf_string_steal(sbuf);
1207                 eina_strbuf_free(sbuf);
1208                 return image_path;
1209         }
1210
1211         eina_strbuf_free(sbuf);
1212         return NULL;
1213 }
1214
1215 static char *efl_to_image_path(AppData *ad, int type_index, const char *str)
1216 {
1217         DBG("str: %s", str);
1218         Eina_Strbuf *sbuf = eina_strbuf_new();
1219         Eina_Bool image_path_exists = EINA_FALSE;
1220         int len = SAFE_STRLEN(str);
1221         char *p = entry_convert_emoticon_to_normal_text((char *)str);
1222         char *s, *temp;
1223         char *image_path = NULL;
1224         temp = p;
1225         if (type_index == ATOM_INDEX_EFL)
1226         {
1227                 for (s = p; (p - s) <= len; p++)
1228                 {
1229                         if (*p == '<')
1230                         {
1231                                 if (!SAFE_STRNCMP((p + 1), "item", 3))
1232                                 {
1233                                         for (p += 5; *p != 'h'; p++);
1234                                         if (!SAFE_STRNCMP(p, "href=file:/", 11))
1235                                         {
1236                                                 p += 11;
1237                                                 s = p;
1238                                                 for (; *p != '>'; p++);
1239                                                 eina_strbuf_append_length(sbuf, s, p - s);
1240                                                 image_path_exists = EINA_TRUE;
1241                                                 break;
1242                                         }
1243                                         else if (!SAFE_STRNCMP(p, "href=", 5))
1244                                         {
1245                                                 p += 5;
1246                                                 s = p;
1247                                                 for (; *p != '>'; p++);
1248                                                 eina_strbuf_append_length(sbuf, s, p - s);
1249                                                 image_path_exists = EINA_TRUE;
1250                                                 break;
1251                                         }
1252                                 }
1253                         }
1254                 }
1255         }
1256         FREE(temp);
1257         if (image_path_exists)
1258         {
1259                 image_path = eina_strbuf_string_steal(sbuf);
1260                 eina_strbuf_free(sbuf);
1261                 return image_path;
1262         }
1263
1264         eina_strbuf_free(sbuf);
1265         return NULL;
1266 }
1267
1268 static char *markup_to_entry(AppData *ad, int type_index, const char *str)
1269 {
1270         CALLED();
1271         if (!str)
1272                 return NULL;
1273
1274         Eina_Strbuf *strbuf = eina_strbuf_new();
1275         if (!strbuf)
1276                 return SAFE_STRDUP(str);
1277         eina_strbuf_prepend(strbuf, "<font_size=28><color=#000000FF>");
1278
1279         const char *trail = str;
1280
1281         while (trail && *trail)
1282         {
1283                 const char *pretrail = trail;
1284                 unsigned long length;
1285                 char *temp;
1286                 char *endtag;
1287
1288                 trail = SAFE_STRCHR(trail, '<');
1289                 if (!trail)
1290                 {
1291                         eina_strbuf_append(strbuf, pretrail);
1292                         break;
1293                 }
1294                 endtag = SAFE_STRCHR(trail, '>');
1295                 if (!endtag)
1296                         break;
1297
1298                 length = trail - pretrail;
1299
1300                 temp = SAFE_STRNDUP(pretrail, length);
1301                 if (!temp)
1302                 {
1303                         trail++;
1304                         continue;
1305                 }
1306
1307                 eina_strbuf_append(strbuf, temp);
1308                 FREE(temp);
1309                 trail++;
1310
1311                 if (trail[0] == '/')
1312                 {
1313                         trail = endtag + 1;
1314                         continue;
1315                 }
1316
1317                 if (!SAFE_STRNCMP(trail, "br", 2))
1318                 {
1319                         eina_strbuf_append(strbuf, "<br>");
1320                         trail = endtag + 1;
1321                         continue;
1322                 }
1323                 trail = endtag + 1;
1324         }
1325
1326         if (type_index == ATOM_INDEX_HTML)
1327                 eina_strbuf_replace_all(strbuf, "&nbsp;", " ");
1328
1329         char *entry_str = eina_strbuf_string_steal(strbuf);
1330         eina_strbuf_free(strbuf);
1331         return entry_str;
1332 }
1333
1334 static char *polaris_to_entry(AppData *ad, int type_index, const char *str)
1335 {
1336         DBG("str: %s", str);
1337         return markup_to_entry(ad, type_index, str);
1338 }
1339
1340 static char *html_to_entry(AppData *ad, int type_index, const char *str)
1341 {
1342         DBG("str: %s", str);
1343         return markup_to_entry(ad, type_index, str);
1344 }
1345
1346 static int entry_emoticon_origin_string(char **src_text, int* item_length)
1347 {
1348         int i = 0;
1349         char *start_item = NULL;
1350         char *end_item = NULL;
1351         char *emoticon = NULL;
1352
1353         int start_item_pos = 0;
1354         int end_item_pos = 0;
1355         int emoticon_pos = 0;
1356
1357         char href_buf[50] = {0, };
1358
1359         start_item = strstr(*src_text, "<item");
1360
1361         if (start_item)
1362                 start_item_pos = strlen(*src_text) - strlen(start_item);
1363
1364         end_item = strchr(*src_text, '>');
1365
1366         if (end_item)
1367                 end_item_pos = strlen(*src_text) - strlen(end_item);
1368
1369         if (start_item_pos >= end_item_pos)
1370                 return ENTRY_EMOTICON_NONE;
1371
1372         for (i = 1; i < ENTRY_EMOTICON_MAX; i++) {
1373                 bzero(href_buf, sizeof(href_buf));
1374                 snprintf(href_buf, sizeof(href_buf), "href=%s", emotion_name_table[i].emoticon_name);
1375                 emoticon = strstr(*src_text, href_buf);
1376                 if (emoticon) {
1377                         emoticon_pos = strlen(*src_text) - strlen(emoticon);
1378
1379                         if (emoticon_pos > start_item_pos && emoticon_pos < end_item_pos) {
1380                                 *src_text += start_item_pos;
1381                                 *item_length = end_item_pos - start_item_pos + 1;
1382                                 return i;
1383                         }
1384                 }
1385         }
1386
1387         return ENTRY_EMOTICON_NONE;
1388 }
1389
1390 char *entry_convert_emoticon_to_normal_text(const char *src_text)
1391 {
1392         char *remain_text = (char *)src_text;
1393         char *dst_str = NULL;
1394         const char *str;
1395
1396         Eina_Strbuf *msg_data = eina_strbuf_new();
1397
1398         while (*remain_text) {
1399                 char *text_start = remain_text;
1400                 int emoticon = ENTRY_EMOTICON_NONE;
1401                 int emoticon_txt_length = 0;
1402
1403                 emoticon = entry_emoticon_origin_string(&remain_text, &emoticon_txt_length);
1404
1405                 if (emoticon != ENTRY_EMOTICON_NONE) {
1406                         eina_strbuf_append_length(msg_data, text_start, remain_text - text_start);
1407                         eina_strbuf_append_printf(msg_data, "%s", emotion_name_table[emoticon].text);
1408
1409                         remain_text = remain_text + emoticon_txt_length;
1410
1411                         if (strncmp(remain_text, "</item>", strlen("</item>")) == 0) {
1412                                 remain_text = remain_text + strlen("</item>");
1413                         }
1414
1415                         if (*remain_text == '\0')
1416                                 break;
1417                 } else {
1418                         eina_strbuf_append(msg_data, text_start);
1419                         break;
1420                 }
1421         }
1422         str = eina_strbuf_string_get(msg_data);
1423         if (str) dst_str = strdup(str);
1424         eina_strbuf_free(msg_data);
1425
1426         return dst_str;
1427 }
1428
1429 static char *efl_to_entry(AppData *ad, int type_index, const char *str)
1430 {
1431         DBG("str: %s", str);
1432
1433         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1434         char *normal_text = markup_to_entry(ad, type_index, emoticon_text);
1435
1436         return normal_text;
1437 }
1438
1439 static char *image_path_to_entry(AppData *ad, int type_index, const char *str)
1440 {
1441         CALLED();
1442         return NULL;
1443 }
1444
1445 static char *text_to_entry(AppData *ad, int type_index, const char *str)
1446 {
1447         DBG("str: %s", str);
1448         char *markup = NULL;
1449         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1450         markup = (char*)evas_textblock_text_utf8_to_markup(NULL, emoticon_text);
1451         char *for_entry = markup_to_entry(ad, type_index, markup);
1452         FREE(markup);
1453         FREE(emoticon_text);
1454         return for_entry;
1455 }
1456
1457 static Eina_List *make_tag_list(int type_index, const char *str)
1458 {
1459         Eina_List *nodeList = NULL;
1460         PTagNode nodeData;
1461
1462         nodeData = _get_start_node(str);
1463
1464         while (nodeData)
1465         {
1466                 nodeList = eina_list_append(nodeList, nodeData);
1467                 nodeData = _get_next_node(nodeData);
1468         }
1469
1470         _link_match_tags(nodeList);
1471
1472         switch(type_index)
1473         {
1474                 case ATOM_INDEX_EFL:
1475                         _set_EFL_tag_data(nodeList);
1476                         break;
1477                 case ATOM_INDEX_HTML:
1478                         _set_HTML_tag_data(nodeList);
1479                         break;
1480                 default:
1481                         WRN("wrong index: %d", type_index);
1482         }
1483
1484         _dumpNode(nodeList);
1485         return nodeList;
1486 }
1487
1488 static void cleanup_tag_list(Eina_List *nodeList)
1489 {
1490         Eina_List *trail;
1491         PTagNode nodeData;
1492
1493         EINA_LIST_FOREACH(nodeList, trail, nodeData)
1494                 _delete_node(nodeData);
1495         eina_list_free(nodeList);
1496 }
1497
1498 static char *html_to_efl(AppData *ad, int type_index, const char *str)
1499 {
1500         CALLED();
1501         Eina_List *nodeList = NULL;
1502         nodeList = make_tag_list(type_index, str);
1503         char *ret = _convert_to_edje(nodeList);
1504         DBG("efl: %s", ret);
1505         cleanup_tag_list(nodeList);
1506
1507         return ret;
1508 }
1509
1510 static char *efl_to_html(AppData *ad, int type_index, const char *str)
1511 {
1512         CALLED();
1513         Eina_List *nodeList = NULL;
1514         nodeList = make_tag_list(type_index, str);
1515         char *ret = _convert_to_html(nodeList);
1516         DBG("html: %s", ret);
1517         cleanup_tag_list(nodeList);
1518
1519         return ret;
1520 }
1521
1522 static char *text_to_html(AppData *ad, int type_index, const char *str)
1523 {
1524         DBG("str: %s", str);
1525         char *markup = NULL;
1526         markup = (char*)evas_textblock_text_utf8_to_markup(NULL, str);
1527         char *html = efl_to_html(ad, ATOM_INDEX_EFL, markup);
1528         FREE(markup);
1529         return html;
1530 }
1531
1532 static char *text_to_efl(AppData *ad, int type_index, const char *str)
1533 {
1534         DBG("str: %s", str);
1535         char *ret = NULL;
1536         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1537         ret = (char*)evas_textblock_text_utf8_to_markup(NULL, emoticon_text);
1538         FREE(emoticon_text);
1539         return ret;
1540 }
1541
1542 static char *to_text(AppData *ad, int type_index, const char *str)
1543 {
1544         DBG("str: %s", str);
1545         char *entry_text = NULL;
1546
1547         if (type_index == ATOM_INDEX_HTML)
1548         {
1549                 Eina_Strbuf *buf = eina_strbuf_new();
1550                 if (buf)
1551                 {
1552                         char *html;
1553                         eina_strbuf_append(buf, str);
1554                         eina_strbuf_replace_all(buf, "&nbsp;", " ");
1555                         html = eina_strbuf_string_steal(buf);
1556                         eina_strbuf_free(buf);
1557                         entry_text = (char*)evas_textblock_text_markup_to_utf8(NULL, html);
1558                         free(html);
1559                         return entry_text;
1560                 }
1561         }
1562
1563         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1564         if (emoticon_text)
1565         {
1566                 char *tmp;
1567                 tmp = markup_to_entry(ad, type_index, emoticon_text);
1568                 entry_text = evas_textblock_text_markup_to_utf8(NULL, tmp);
1569                 free(tmp);
1570                 if (entry_text) strcat(entry_text, "\0");
1571                 FREE(emoticon_text);
1572         }
1573         return entry_text;
1574 }
1575