861540f74941e4307abbecfb19abc8ce20e6d455
[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)
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                         char *modify = SAFE_STRNDUP(value, xpos - value);
667                         if (modify)
668                         {
669                                 FREE(data->width);
670                                 data->width = modify;
671                         }
672                         modify = SAFE_STRNDUP(xpos + 1, absizeLen - (xpos - value) - 1);
673                         if (modify)
674                         {
675                                 FREE(data->height);
676                                 data->height = modify;
677                         }
678                         DBG("image width: -%s-, height: -%s-", data->width, data->height);
679                 }
680                 FREE(value);
681         }
682         return data;
683 }
684
685 static void
686 _set_EFL_tag_data(Eina_List* nodes)
687 {
688         PTagNode trail;
689         Eina_List *l;
690
691         EINA_LIST_FOREACH(nodes, l, trail)
692         {
693                 if (!trail || !trail->tag || trail->tag[0] == '\0') continue;
694
695                 if (!SAFE_STRCMP("font", trail->tag) || !SAFE_STRCMP("color", trail->tag))
696                         trail->tagData = _set_EFL_font_data(trail->tagData, trail->tag_str);
697                 else if (!SAFE_STRCMP("item", trail->tag))
698                         trail->tagData = _set_EFL_item_data(trail->tagData, trail->tag_str);
699         }
700 }
701
702 static PFontTagData
703 _set_HTML_font_data(PFontTagData data, const char *tag_str)
704 {
705         char *value;
706
707         if (!data)
708                 data = CALLOC(1, sizeof(FontTagData));
709         value = _get_tag_value(tag_str, "size");
710         freeAndAssign(data->size, value);
711         value = _get_tag_value(tag_str, "color");
712         freeAndAssign(data->color, value);
713         value = _get_tag_value(tag_str, "bgcolor");
714         freeAndAssign(data->bg_color, value);
715         value = _get_tag_value(tag_str, "face");
716         freeAndAssign(data->name, value);
717
718         return data;
719 }
720
721 static PItemTagData
722 _set_HTML_img_data(PItemTagData data, const char *tag_str)
723 {
724         char *value;
725
726         if (!data)
727                 data = CALLOC(1, sizeof(ItemTagData));
728         value = _get_tag_value(tag_str, "src");
729         if (value)
730         {
731                 char *path = SAFE_STRSTR(value, "file://");
732                 if (path)
733                 {
734                         char *modify = MALLOC(sizeof(char) * (SAFE_STRLEN(value) + 1));
735                         SAFE_STRNCPY(modify, "file://", 8);
736                         path += 7;
737                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
738                         {
739                                 path++;
740                         }
741                         SAFE_STRCAT(modify, path);
742                         data->href = modify;
743                         DBG("image src ---%s---", data->href);
744                         FREE(value);
745                 }
746                 else
747                         freeAndAssign(data->href, value);
748         }
749
750         value = _get_tag_value(tag_str, "width");
751         freeAndAssign(data->width, value);
752         value = _get_tag_value(tag_str, "height");
753         freeAndAssign(data->height, value);
754         return data;
755 }
756
757 static void
758 _set_HTML_tag_data(Eina_List* nodes)
759 {
760         PTagNode trail;
761         Eina_List *l;
762
763         EINA_LIST_FOREACH(nodes, l, trail)
764         {
765                 if (!trail || !trail->tag || trail->tag[0] == '\0') continue;
766
767                 if (!SAFE_STRCMP("font", trail->tag) || !SAFE_STRCMP("color", trail->tag))
768                         trail->tagData = _set_HTML_font_data(trail->tagData, trail->tag_str);
769                 else if (!SAFE_STRCMP("img", trail->tag))
770                         trail->tagData = _set_HTML_img_data(trail->tagData, trail->tag_str);
771         }
772 }
773
774 static void
775 _dumpNode(Eina_List* nodes)
776 {
777         PTagNode trail;
778         Eina_List *l;
779
780         EINA_LIST_FOREACH(nodes, l, trail)
781         {
782                 if (!trail) continue;
783
784                 DBG("tag: %s, tag_str: %s, str: %s, tagPosType: %d",
785                                 trail->tag, trail->tag_str, trail->str, trail->tagPosType);
786                 DBG("matchTag: %x", (unsigned int)trail->matchTag);
787                 if (trail->matchTag)
788                         DBG("matchTag->tag_str: %s", trail->matchTag->tag_str);
789                 if (trail->tagData)
790                 {
791                         if (!SAFE_STRCMP(trail->tag, "font"))
792                         {
793                                 PFontTagData data = trail->tagData;
794                                 DBG(" tagData->name: %s, tagData->color: %s, tagData->size: %s, tagData->bg_color: %s",
795                                                 data->name, data->color, data->size, data->bg_color);
796                         }
797                         else if (!SAFE_STRCMP(trail->tag, "item") || !SAFE_STRCMP(trail->tag, "img"))
798                         {
799                                 PItemTagData data = trail->tagData;
800                                 DBG(" tagData->href: %s, tagData->width: %s, tagData->height: %s",
801                                                 data->href, data->width, data->height);
802                         }
803                         else
804                                 WRN("ERROR!!!! not need tagData");
805                 }
806         }
807 }
808
809 static char *
810 _convert_to_html(Eina_List* nodes)
811 {
812         PTagNode trail;
813         Eina_List *l;
814
815         Eina_Strbuf *html = eina_strbuf_new();
816
817         int tableCnt = sizeof(_EFLtoHTMLConvertTable) / sizeof(TagTable);
818
819         EINA_LIST_FOREACH(nodes, l, trail)
820         {
821                 if (!trail) continue;
822
823                 if (trail->tag)
824                 {
825                         char *tagName = trail->tagPosType == TAGPOS_END ?
826                                 trail->matchTag->tag : trail->tag;
827                         int j;
828                         for(j = 0; j < tableCnt; j++)
829                         {
830                                 if (!SAFE_STRCMP(_EFLtoHTMLConvertTable[j].src, tagName))
831                                 {
832                                         switch(trail->tagPosType)
833                                         {
834                                                 case TAGPOS_END:
835                                                         eina_strbuf_append(html, "</");
836                                                         break;
837                                                 default:
838                                                         eina_strbuf_append(html, "<");
839                                                         break;
840                                         }
841
842                                         eina_strbuf_append(html, _EFLtoHTMLConvertTable[j].dst);
843                                         if (trail->tagPosType != TAGPOS_END)
844                                         {
845                                                 if (!SAFE_STRCMP(_EFLtoHTMLConvertTable[j].src, "font"))
846                                                 {
847                                                         PFontTagData data = trail->tagData;
848                                                         if (data->name)
849                                                         {
850                                                         }
851                                                         if (data->color)
852                                                         {
853                                                                 char *color = SAFE_STRDUP(data->color);
854                                                                 if (color && color[0] == '#' && SAFE_STRLEN(color) == 9)
855                                                                 {
856                                                                         color[7] = '\0';
857                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", color);
858                                                                 }
859                                                                 else
860                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", data->color);
861                                                                 if (color)
862                                                                         FREE(color);
863                                                         }
864                                                         if (data->size)
865                                                                 eina_strbuf_append_printf(html, " size=\"%s\"", data->size);
866                                                         if (data->bg_color)
867                                                         {
868                                                         }
869                                                 }
870                                                 else if (!SAFE_STRCMP(_EFLtoHTMLConvertTable[j].src, "item"))
871                                                 {
872                                                         PItemTagData data = trail->tagData;
873                                                         if (data->href)
874                                                                 eina_strbuf_append_printf(html, " src=\"%s\"", data->href);
875                                                         if (data->width)
876                                                                 eina_strbuf_append_printf(html, " width=\"%s\"", data->width);
877                                                         if (data->height)
878                                                                 eina_strbuf_append_printf(html, " height=\"%s\"", data->height);
879                                                 }
880                                         }
881                                         switch(trail->tagPosType)
882                                         {
883                                                 /* closed tag does not need in HTML
884                                                    case TAGPOS_ALONE:
885                                                    eina_strbuf_append(html, " />");
886                                                    break;*/
887                                                 default:
888                                                         eina_strbuf_append(html, ">");
889                                                         break;
890                                         }
891                                         break;
892                                 }
893                         }
894                 }
895                 if (trail->str)
896                         eina_strbuf_append(html, trail->str);
897         }
898
899         eina_strbuf_replace_all(html, "  ", " &nbsp;");
900         char *ret = eina_strbuf_string_steal(html);
901         eina_strbuf_free(html);
902         return ret;
903 }
904
905 #define IMAGE_DEFAULT_WIDTH "240"
906 #define IMAGE_DEFAULT_HEIGHT "180"
907
908
909 static char *
910 _convert_to_edje(Eina_List* nodes)
911 {
912         PTagNode trail;
913         Eina_List *l;
914
915         Eina_Strbuf *edje = eina_strbuf_new();
916
917         int tableCnt = sizeof(_HTMLtoEFLConvertTable) / sizeof(TagTable);
918
919         EINA_LIST_FOREACH(nodes, l, trail)
920         {
921                 if (!trail) continue;
922
923                 if (trail->tag)
924                 {
925                         char *tagName = trail->tagPosType == TAGPOS_END ?
926                                 trail->matchTag->tag : trail->tag;
927                         int j;
928                         for(j = 0; j < tableCnt; j++)
929                         {
930                                 if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, tagName))
931                                 {
932                                         if (_HTMLtoEFLConvertTable[j].dst[0] != '\0')
933                                         {
934                                                 switch(trail->tagPosType)
935                                                 {
936                                                         case TAGPOS_END:
937                                                                 eina_strbuf_append(edje, "</");
938                                                                 break;
939                                                         default:
940                                                                 eina_strbuf_append(edje, "<");
941                                                                 break;
942                                                 }
943
944                                                 eina_strbuf_append(edje, _HTMLtoEFLConvertTable[j].dst);
945                                         }
946                                         if (trail->tagPosType != TAGPOS_END)
947                                         {
948                                                 if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, "font"))
949                                                 {
950                                                         PFontTagData data = trail->tagData;
951                                                         if (data->name)
952                                                         {
953                                                         }
954                                                         if (data->color)
955                                                         {
956                                                                 if (data->color[0] == '#' && SAFE_STRLEN(data->color) == 7)
957                                                                         eina_strbuf_append_printf(edje, "<color=%sff>", data->color);
958                                                                 else
959                                                                         eina_strbuf_append_printf(edje, "<color=%s>", data->color);
960
961                                                         }
962                                                         if (data->size)
963                                                                 eina_strbuf_append_printf(edje, "<font_size=%s>", data->size);
964                                                         if (data->bg_color)
965                                                         {
966                                                         }
967                                                         break;
968                                                 }
969                                                 else if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, "img"))
970                                                 {
971                                                         PItemTagData data = trail->tagData;
972                                                         char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT;
973                                                         if (data->width)
974                                                                 width = data->width;
975                                                         if (data->height)
976                                                                 height = data->height;
977                                                         eina_strbuf_append_printf(edje, " absize=%sx%s", width, height);
978                                                         if (data->href)
979                                                                 eina_strbuf_append_printf(edje, " href=%s></item>", data->href);
980                                                         break;
981                                                 }
982                                         }
983                                         else
984                                         {
985                                                 if (_HTMLtoEFLConvertTable[j].dst[0] == '\0')
986                                                 {
987                                                         if (!SAFE_STRCMP(_HTMLtoEFLConvertTable[j].src, "font"))
988                                                         {
989                                                                 if (trail->matchTag->tagData)
990                                                                 {
991                                                                         PFontTagData data = trail->matchTag->tagData;
992                                                                         if (data->name)
993                                                                         {
994                                                                         }
995                                                                         if (data->color)
996                                                                                 eina_strbuf_append_printf(edje, "</color>");
997                                                                         if (data->size)
998                                                                                 eina_strbuf_append_printf(edje, "</font>");
999                                                                         if (data->bg_color)
1000                                                                         {
1001                                                                         }
1002                                                                         break;
1003                                                                 }
1004                                                         }
1005                                                 }
1006                                         }
1007                                         switch(trail->tagPosType)
1008                                         {
1009                                                 /* not support in efl
1010                                                    case TAGPOS_ALONE:
1011                                                    eina_strbuf_append(edje, " />");
1012                                                    break;
1013                                                  */
1014                                                 default:
1015                                                         eina_strbuf_append(edje, ">");
1016                                                         break;
1017                                         }
1018                                         break;
1019                                 }
1020                         }/* for(j = 0; j < tableCnt; j++) end */
1021                 }
1022                 if (trail->str)
1023                         eina_strbuf_append(edje, trail->str);
1024         }
1025
1026         eina_strbuf_replace_all(edje, "&nbsp;", " ");
1027         char *ret = eina_strbuf_string_steal(edje);
1028         eina_strbuf_free(edje);
1029         return ret;
1030 }
1031
1032 char *string_for_entry_get(AppData *ad, int type_index, const char *str)
1033 {
1034         DBG("type_index: %d str: %s ", type_index, str);
1035         if (ad->targetAtoms[type_index].convert_to_entry)
1036                 return ad->targetAtoms[type_index].convert_to_entry(ad, type_index, str);
1037         return NULL;
1038 }
1039
1040 char *string_for_image_path_get(AppData *ad, int type_index, const char *str)
1041 {
1042         DBG("type_index: %d str: %s ", type_index, str);
1043         char *image_path = NULL;
1044
1045         if (type_index == ATOM_INDEX_HTML)
1046                 image_path = html_to_image_path(ad, type_index, str);
1047         else if (type_index == ATOM_INDEX_EFL)
1048                 image_path = efl_to_image_path(ad, type_index, str);
1049
1050         return image_path;
1051 }
1052 /*
1053 static char *make_close_tag(Eina_List* nodes)
1054 {
1055         CALLED();
1056         PTagNode trail;
1057         Eina_List *l;
1058
1059         Eina_Strbuf *tag_str = eina_strbuf_new();
1060
1061         EINA_LIST_FOREACH(nodes, l, trail)
1062         {
1063                 if (trail->tag)
1064                 {
1065                         if (trail->tag_str)
1066                                 eina_strbuf_append(tag_str, trail->tag_str);
1067                         else
1068                         {
1069                                 eina_strbuf_append(tag_str, "<");
1070                                 eina_strbuf_append(tag_str, trail->tag);
1071                                 eina_strbuf_append(tag_str, ">");
1072                         }
1073                 }
1074                 if (trail->str)
1075                         eina_strbuf_append(tag_str, trail->str);
1076         }
1077
1078         char *ret = eina_strbuf_string_steal(tag_str);
1079         eina_strbuf_free(tag_str);
1080         return ret;
1081 }
1082 */
1083 static char *do_not_convert(AppData *ad, int type_index, const char *str)
1084 {
1085         DBG("str: %s", str);
1086         if (type_index != ATOM_INDEX_HTML)
1087         {
1088                 char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1089                 return emoticon_text;
1090         }
1091         return SAFE_STRDUP(str);
1092 }
1093 /*
1094    static char *efl_to_efl(AppData *ad, int type_index, const char *str)
1095    {
1096    CALLED();
1097    return NULL;
1098    }
1099
1100    static char *html_to_html(AppData *ad, int type_index, const char *str)
1101    {
1102    CALLED();
1103    return NULL;
1104    }
1105  */
1106
1107 #define IMAGE_DEFAULT_WIDTH "240"
1108 #define IMAGE_DEFAULT_HEIGHT "180"
1109 static char *make_image_path_tag(int type_index, const char *str)
1110 {
1111         char *img_tag_str = "file://%s";
1112         char *efl_img_tag = "<item absize="IMAGE_DEFAULT_WIDTH"x"IMAGE_DEFAULT_HEIGHT" href=file://%s>";
1113         char *html_img_tag = "<img src=\"file://%s\">";
1114
1115         switch (type_index)
1116         {
1117                 case ATOM_INDEX_HTML:
1118                         img_tag_str = html_img_tag;
1119                         break;
1120                 case ATOM_INDEX_EFL:
1121                         img_tag_str = efl_img_tag;
1122                         break;
1123                 case ATOM_INDEX_TEXT:
1124                 case ATOM_INDEX_IMAGE:
1125                         break;
1126                 default:
1127                         ERR("wrong type_index: %d", type_index);
1128                         return NULL;
1129         }
1130
1131         size_t len = snprintf(NULL, 0, img_tag_str, str) + 1;
1132         char *ret = MALLOC(sizeof(char) * len);
1133         if (ret)
1134                 snprintf(ret, len, img_tag_str, str);
1135         return ret;
1136 }
1137
1138 /*
1139 static char *image_path_to_text(AppData *ad, int type_index, const char *str)
1140 {
1141         DBG("str: %s", str);
1142         return make_image_path_tag(ATOM_INDEX_TEXT, str);
1143 }
1144 */
1145
1146 static char *image_path_to_html(AppData *ad, int type_index, const char *str)
1147 {
1148         DBG("str: %s", str);
1149         return make_image_path_tag(ATOM_INDEX_HTML, str);
1150 }
1151
1152 static char *image_path_to_efl(AppData *ad, int type_index, const char *str)
1153 {
1154         DBG("str: %s", str);
1155         return make_image_path_tag(ATOM_INDEX_EFL, str);
1156 }
1157
1158 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str)
1159 {
1160         DBG("str: %s", str);
1161         return make_image_path_tag(ATOM_INDEX_IMAGE, str);
1162 }
1163
1164 static char *html_to_image_path(AppData *ad, int type_index, const char *str)
1165 {
1166         DBG("str: %s", str);
1167         Eina_Strbuf *sbuf = eina_strbuf_new();
1168         Eina_Bool image_path_exists = EINA_FALSE;
1169         int len = SAFE_STRLEN(str);
1170         char *p = (char *)str;
1171         char *s;
1172         char *image_path = NULL;
1173
1174         if (type_index == ATOM_INDEX_HTML)
1175         {
1176                 for (s = p; (p - s) <= len; p++)
1177                 {
1178                         if (*p == '<')
1179                         {
1180                                 if (!SAFE_STRNCMP((p + 1), "img", 3))
1181                                 {
1182                                         for (p += 4; *p != '"'; p++);
1183                                         if (!SAFE_STRNCMP((p + 1), "http:/", 6) || !SAFE_STRNCMP((p + 1), "file:/", 6))
1184                                         {
1185                                                 if (!SAFE_STRNCMP((p + 1), "http:/", 6))
1186                                                         ad->clipdrawer->http_path = EINA_TRUE;
1187                                                 else
1188                                                         ad->clipdrawer->http_path = EINA_FALSE;
1189
1190                                                 p += 7;
1191                                                 s = p;
1192                                                 for (; *p != '"'; p++);
1193                                                 eina_strbuf_append_length(sbuf, s, p - s);
1194                                                 image_path_exists = EINA_TRUE;
1195                                                 break;
1196                                         }
1197                                         else if ((*(p + 1) == '/'))
1198                                         {
1199                                                 p++;
1200                                                 s = p;
1201                                                 for (; *p != '"'; p++);
1202                                                 eina_strbuf_append_length(sbuf, s, p - s);
1203                                                 image_path_exists = EINA_TRUE;
1204                                                 ad->clipdrawer->http_path = EINA_FALSE;
1205                                                 break;
1206                                         }
1207                                 }
1208                         }
1209                 }
1210         }
1211
1212         if (image_path_exists)
1213         {
1214                 //Replace the space Unicode character(%20).
1215                 eina_strbuf_replace_all(sbuf, "%20", " ");
1216                 image_path = eina_strbuf_string_steal(sbuf);
1217                 eina_strbuf_free(sbuf);
1218                 return image_path;
1219         }
1220
1221         eina_strbuf_free(sbuf);
1222         return NULL;
1223 }
1224
1225 static char *efl_to_image_path(AppData *ad, int type_index, const char *str)
1226 {
1227         DBG("str: %s", str);
1228         Eina_Strbuf *sbuf = eina_strbuf_new();
1229         Eina_Bool image_path_exists = EINA_FALSE;
1230         int len = SAFE_STRLEN(str);
1231         char *p = entry_convert_emoticon_to_normal_text((char *)str);
1232         char *s = NULL;
1233         char *image_path = NULL;
1234
1235         if (!p) return NULL;
1236
1237         if (type_index == ATOM_INDEX_EFL)
1238         {
1239                 for (s = p; (p - s) <= len; p++)
1240                 {
1241                         if (*p == '<')
1242                         {
1243                                 if (!SAFE_STRNCMP((p + 1), "item", 3))
1244                                 {
1245                                         for (p += 5; *p != 'h'; p++);
1246                                         if (!SAFE_STRNCMP(p, "href=file:/", 11))
1247                                         {
1248                                                 p += 11;
1249                                                 s = p;
1250                                                 for (; *p != '>'; p++);
1251                                                 eina_strbuf_append_length(sbuf, s, p - s);
1252                                                 image_path_exists = EINA_TRUE;
1253                                                 break;
1254                                         }
1255                                         else if (!SAFE_STRNCMP(p, "href=", 5))
1256                                         {
1257                                                 p += 5;
1258                                                 s = p;
1259                                                 for (; *p != '>'; p++);
1260                                                 eina_strbuf_append_length(sbuf, s, p - s);
1261                                                 image_path_exists = EINA_TRUE;
1262                                                 break;
1263                                         }
1264                                 }
1265                         }
1266                 }
1267         }
1268
1269         if (image_path_exists)
1270         {
1271                 image_path = eina_strbuf_string_steal(sbuf);
1272                 eina_strbuf_free(sbuf);
1273                 free(s);
1274                 return image_path;
1275         }
1276
1277         eina_strbuf_free(sbuf);
1278         if (s)
1279                 free(s);
1280         return NULL;
1281 }
1282
1283 static char *markup_to_entry(AppData *ad, int type_index, const char *str)
1284 {
1285         CALLED();
1286         if (!str)
1287                 return NULL;
1288
1289         Eina_Strbuf *strbuf = eina_strbuf_new();
1290         if (!strbuf)
1291                 return SAFE_STRDUP(str);
1292         eina_strbuf_prepend(strbuf, "<font_size=28><color=#000000FF>");
1293
1294         const char *trail = str;
1295
1296         while (trail && *trail)
1297         {
1298                 const char *pretrail = trail;
1299                 unsigned long length;
1300                 char *temp;
1301                 char *endtag;
1302
1303                 trail = SAFE_STRCHR(trail, '<');
1304                 if (!trail)
1305                 {
1306                         eina_strbuf_append(strbuf, pretrail);
1307                         break;
1308                 }
1309                 endtag = SAFE_STRCHR(trail, '>');
1310                 if (!endtag)
1311                         break;
1312
1313                 length = trail - pretrail;
1314
1315                 temp = SAFE_STRNDUP(pretrail, length);
1316                 if (!temp)
1317                 {
1318                         trail++;
1319                         continue;
1320                 }
1321
1322                 eina_strbuf_append(strbuf, temp);
1323                 FREE(temp);
1324                 trail++;
1325
1326                 if (trail[0] == '/')
1327                 {
1328                         trail = endtag + 1;
1329                         continue;
1330                 }
1331
1332                 if (!SAFE_STRNCMP(trail, "br", 2))
1333                 {
1334                         eina_strbuf_append(strbuf, "<br>");
1335                         trail = endtag + 1;
1336                         continue;
1337                 }
1338                 trail = endtag + 1;
1339         }
1340
1341         if (type_index == ATOM_INDEX_HTML)
1342                 eina_strbuf_replace_all(strbuf, "&nbsp;", " ");
1343
1344         char *entry_str = eina_strbuf_string_steal(strbuf);
1345         eina_strbuf_free(strbuf);
1346         return entry_str;
1347 }
1348
1349 static char *polaris_to_entry(AppData *ad, int type_index, const char *str)
1350 {
1351         DBG("str: %s", str);
1352         return markup_to_entry(ad, type_index, str);
1353 }
1354
1355 static char *html_to_entry(AppData *ad, int type_index, const char *str)
1356 {
1357         DBG("str: %s", str);
1358         return markup_to_entry(ad, type_index, str);
1359 }
1360
1361 static int entry_emoticon_origin_string(char **src_text, int* item_length)
1362 {
1363         int i = 0;
1364         char *start_item = NULL;
1365         char *end_item = NULL;
1366         char *emoticon = NULL;
1367
1368         int start_item_pos = 0;
1369         int end_item_pos = 0;
1370         int emoticon_pos = 0;
1371
1372         char href_buf[50] = {0, };
1373
1374         start_item = strstr(*src_text, "<item");
1375
1376         if (start_item)
1377                 start_item_pos = strlen(*src_text) - strlen(start_item);
1378
1379         end_item = strchr(*src_text, '>');
1380
1381         if (end_item)
1382                 end_item_pos = strlen(*src_text) - strlen(end_item);
1383
1384         if (start_item_pos >= end_item_pos)
1385                 return ENTRY_EMOTICON_NONE;
1386
1387         for (i = 1; i < ENTRY_EMOTICON_MAX; i++) {
1388                 bzero(href_buf, sizeof(href_buf));
1389                 snprintf(href_buf, sizeof(href_buf), "href=%s", emotion_name_table[i].emoticon_name);
1390                 emoticon = strstr(*src_text, href_buf);
1391                 if (emoticon) {
1392                         emoticon_pos = strlen(*src_text) - strlen(emoticon);
1393
1394                         if (emoticon_pos > start_item_pos && emoticon_pos < end_item_pos) {
1395                                 *src_text += start_item_pos;
1396                                 *item_length = end_item_pos - start_item_pos + 1;
1397                                 return i;
1398                         }
1399                 }
1400         }
1401
1402         return ENTRY_EMOTICON_NONE;
1403 }
1404
1405 char *entry_convert_emoticon_to_normal_text(const char *src_text)
1406 {
1407         char *remain_text = (char *)src_text;
1408         char *dst_str = NULL;
1409
1410         Eina_Strbuf *msg_data = eina_strbuf_new();
1411
1412         if (!msg_data) return NULL;
1413
1414         while (*remain_text) {
1415                 char *text_start = remain_text;
1416                 int emoticon = ENTRY_EMOTICON_NONE;
1417                 int emoticon_txt_length = 0;
1418
1419                 emoticon = entry_emoticon_origin_string(&remain_text, &emoticon_txt_length);
1420
1421                 if (emoticon != ENTRY_EMOTICON_NONE) {
1422                         eina_strbuf_append_length(msg_data, text_start, remain_text - text_start);
1423                         eina_strbuf_append_printf(msg_data, "%s", emotion_name_table[emoticon].text);
1424
1425                         remain_text = remain_text + emoticon_txt_length;
1426
1427                         if (strncmp(remain_text, "</item>", strlen("</item>")) == 0) {
1428                                 remain_text = remain_text + strlen("</item>");
1429                         }
1430
1431                         if (*remain_text == '\0')
1432                                 break;
1433                 } else {
1434                         eina_strbuf_append(msg_data, text_start);
1435                         break;
1436                 }
1437         }
1438
1439         dst_str = strdup(eina_strbuf_string_get(msg_data));
1440         eina_strbuf_free(msg_data);
1441
1442         return dst_str;
1443 }
1444
1445 static char *efl_to_entry(AppData *ad, int type_index, const char *str)
1446 {
1447         DBG("str: %s", str);
1448
1449         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1450         char *normal_text = markup_to_entry(ad, type_index, emoticon_text);
1451         FREE(emoticon_text);
1452         return normal_text;
1453 }
1454
1455 static char *image_path_to_entry(AppData *ad, int type_index, const char *str)
1456 {
1457         CALLED();
1458         return NULL;
1459 }
1460
1461 static char *text_to_entry(AppData *ad, int type_index, const char *str)
1462 {
1463         DBG("str: %s", str);
1464         char *markup = NULL;
1465         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1466         markup = (char*)evas_textblock_text_utf8_to_markup(NULL, emoticon_text);
1467         char *for_entry = markup_to_entry(ad, type_index, markup);
1468         FREE(markup);
1469         FREE(emoticon_text);
1470         return for_entry;
1471 }
1472
1473 static Eina_List *make_tag_list(int type_index, const char *str)
1474 {
1475         Eina_List *nodeList = NULL;
1476         PTagNode nodeData;
1477
1478         nodeData = _get_start_node(str);
1479
1480         while (nodeData)
1481         {
1482                 nodeList = eina_list_append(nodeList, nodeData);
1483                 nodeData = _get_next_node(nodeData);
1484         }
1485
1486         _link_match_tags(nodeList);
1487
1488         switch(type_index)
1489         {
1490                 case ATOM_INDEX_EFL:
1491                         _set_EFL_tag_data(nodeList);
1492                         break;
1493                 case ATOM_INDEX_HTML:
1494                         _set_HTML_tag_data(nodeList);
1495                         break;
1496                 default:
1497                         WRN("wrong index: %d", type_index);
1498         }
1499
1500         _dumpNode(nodeList);
1501         return nodeList;
1502 }
1503
1504 static void cleanup_tag_list(Eina_List *nodeList)
1505 {
1506         Eina_List *trail;
1507         PTagNode nodeData;
1508
1509         EINA_LIST_FOREACH(nodeList, trail, nodeData)
1510                 _delete_node(nodeData);
1511         eina_list_free(nodeList);
1512 }
1513
1514 static char *html_to_efl(AppData *ad, int type_index, const char *str)
1515 {
1516         CALLED();
1517         Eina_List *nodeList = NULL;
1518         nodeList = make_tag_list(type_index, str);
1519         char *ret = _convert_to_edje(nodeList);
1520         DBG("efl: %s", ret);
1521         cleanup_tag_list(nodeList);
1522
1523         return ret;
1524 }
1525
1526 static char *efl_to_html(AppData *ad, int type_index, const char *str)
1527 {
1528         CALLED();
1529         Eina_List *nodeList = NULL;
1530         nodeList = make_tag_list(type_index, str);
1531         char *ret = _convert_to_html(nodeList);
1532         DBG("html: %s", ret);
1533         cleanup_tag_list(nodeList);
1534
1535         return ret;
1536 }
1537
1538 static char *text_to_html(AppData *ad, int type_index, const char *str)
1539 {
1540         DBG("str: %s", str);
1541         char *markup = NULL;
1542         markup = (char*)evas_textblock_text_utf8_to_markup(NULL, str);
1543         char *html = efl_to_html(ad, ATOM_INDEX_EFL, markup);
1544         FREE(markup);
1545         return html;
1546 }
1547
1548 static char *text_to_efl(AppData *ad, int type_index, const char *str)
1549 {
1550         DBG("str: %s", str);
1551         char *ret = NULL;
1552         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1553         ret = (char*)evas_textblock_text_utf8_to_markup(NULL, emoticon_text);
1554         FREE(emoticon_text);
1555         return ret;
1556 }
1557
1558 static char *to_text(AppData *ad, int type_index, const char *str)
1559 {
1560         DBG("str: %s", str);
1561         char *entry_text = NULL;
1562
1563         if (type_index == ATOM_INDEX_HTML)
1564         {
1565                 Eina_Strbuf *buf = eina_strbuf_new();
1566                 if (buf)
1567                 {
1568                         char *html;
1569                         eina_strbuf_append(buf, str);
1570                         eina_strbuf_replace_all(buf, "&nbsp;", " ");
1571                         html = eina_strbuf_string_steal(buf);
1572                         eina_strbuf_free(buf);
1573                         entry_text = (char*)evas_textblock_text_markup_to_utf8(NULL, html);
1574                         free(html);
1575                         return entry_text;
1576                 }
1577         }
1578
1579         char *emoticon_text = entry_convert_emoticon_to_normal_text(str);
1580         if (emoticon_text)
1581         {
1582                 entry_text = markup_to_entry(ad, type_index, emoticon_text);
1583                 entry_text = evas_textblock_text_markup_to_utf8(NULL, entry_text);
1584                 if (entry_text) strcat(entry_text, "\0");
1585                 FREE(emoticon_text);
1586         }
1587         return entry_text;
1588 }
1589