--- say.c.original	Sun Sep 14 12:47:07 2003
+++ say.c	Tue Sep 23 15:26:01 2003
@@ -25,7 +25,32 @@
 #include "asterisk.h"
 #include <stdio.h>
 
-#define DIGITS_DIR	AST_SOUNDS "/digits/"
+static int wait_file(struct ast_channel *chan, char *ints, char *file, char *lang) 
+{
+	int res;
+	if ((res = ast_streamfile(chan, file, lang)))
+		ast_log(LOG_WARNING, "Unable to play message %s\n", file);
+	if (!res)
+		res = ast_waitstream(chan, ints);
+	return res;
+}
+
+static int if_wait_file(int res, struct ast_channel *chan, char *ints, char *file, char *lang) 
+{
+	if (res)
+	    return res;
+	return wait_file(chan, ints, file, lang);
+}
+
+static int wait_file_full(struct ast_channel *chan, char *ints, char *file, char *lang, int audiofd, int ctrlfd) 
+{
+	int res;
+	if ((res = ast_streamfile(chan, file, lang)))
+		ast_log(LOG_WARNING, "Unable to play message %s\n", file);
+	if (!res)
+		res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+	return res;
+}
 
 int ast_say_digit_str(struct ast_channel *chan, char *fn2, char *ints, char *lang)
 {
@@ -44,9 +69,7 @@
 			default:
 				snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
 			}
-		res = ast_streamfile(chan, fn, lang);
-		if (!res) 
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 		ast_stopstream(chan);
 		num++;
 	}
@@ -84,17 +107,102 @@
 	return ast_say_digit_str_full(chan, fn2, ints, lang, audiofd, ctrlfd);
 }
 
-int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+static int say_number(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd, int full)
 {
 	int res = 0;
 	int playh = 0;
+        int mf = 1;                     	// +1 = Masculin; -1 = Feminin
 	char fn[256] = "";
-	if (!num) 
+	if (!num) {
+	    if (full)
 		return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-	if (0) {
-	/* XXX Only works for english XXX */
+	    else
+		return ast_say_digits(chan, 0,ints, language);
+	}
+	
+        if (num < 0) {				// Feminin
+            mf = -1;
+            num = -num;
+            }
+
+        if (!strcasecmp(language, "pt")) {      
+		// PORTUGUESE
+                while(!res && num) {
+                        if (num < 20) {
+                                if ((num == 1 || num == 2) && (mf < 0))
+                                    snprintf(fn, sizeof(fn), "digits/%dF", num);
+                                else
+                                    snprintf(fn, sizeof(fn), "digits/%d", num);
+                                num = 0;
+                        } else
+                        if (num < 100) {
+                                snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
+                                if (num % 10)
+                                    playh = 1;
+                                num = num % 10;
+                        } else
+                        if (num < 1000) {
+                                if (num == 100)
+                                    snprintf(fn, sizeof(fn), "digits/100");
+                                else if (num < 200)
+                                    snprintf(fn, sizeof(fn), "digits/100E");
+                                else {
+                                    if (mf < 0 && num > 199)
+                                        snprintf(fn, sizeof(fn), "digits/%dF", (num / 100) * 100);
+                                    else
+                                        snprintf(fn, sizeof(fn), "digits/%d", (num / 100) * 100);
+                                    if (num % 100)
+                                        playh = 1;
+                                }
+                                num = num % 100;
+                        } else
+                        if (num < 1000000) {
+                                if (num > 1999) {
+                            	    res = say_number(chan, (num / 1000) * mf, ints, language, audiofd, ctrlfd, full);
+				    if (res)
+                                        return res;
+                                }
+                                snprintf(fn, sizeof(fn), "digits/1000");
+                                if ((num % 1000) && ((num % 1000) < 100  || !(num % 100)))
+                                    playh = 1;
+                                num = num % 1000;
+                        } else
+                        if (num < 1000000000) {
+                            	res = say_number(chan, (num / 1000000), ints, language, audiofd, ctrlfd, full);
+				if (res)
+                                    return res;
+
+                                if (num < 2000000)
+                                    snprintf(fn, sizeof(fn), "digits/1000000");
+                                else
+                                    snprintf(fn, sizeof(fn), "digits/1000000S");
+
+                                if ((num % 1000000) &&
+                                  // no thousands
+                                  ((!((num / 1000) % 1000) && ((num % 1000) < 100 || !(num % 100))) ||
+                                  // no hundreds and below
+                                  (!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
+                                        playh = 1;
+                                num = num % 1000000;
+                        }
+                        if (!res) {
+				if (full)
+				    res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
+				else
+				    res = wait_file(chan, ints, fn, language);
+                                ast_stopstream(chan);
+                        }
+                        if (!res && playh) {
+				if (full)
+				    res = wait_file_full(chan, ints, "digits/pt-e", language, audiofd, ctrlfd);
+				else
+				    res = wait_file(chan, ints, "digits/pt-e", language);
+                                ast_stopstream(chan);
+                                playh = 0;
+                        }
+                }
 	} else {
-		/* Use english numbers */
+		// ENGLISH by default
 		language = "en";
 		while(!res && (num || playh)) {
 			if (playh) {
@@ -115,16 +223,18 @@
 					num -= ((num / 100) * 100);
 				} else {
 					if (num < 1000000) { /* 1,000,000 */
-						res = ast_say_number_full(chan, num / 1000, ints, language, audiofd, ctrlfd);
+						res = say_number(chan, num / 1000, ints, language, audiofd, ctrlfd, full);
 						if (res)
 							return res;
+
 						num = num % 1000;
 						snprintf(fn, sizeof(fn), "digits/thousand");
 					} else {
 						if (num < 1000000000) {	/* 1,000,000,000 */
-							res = ast_say_number_full(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+							res =say_number(chan, num / 1000000, ints, language, audiofd, ctrlfd, full);
 							if (res)
 								return res;
+
 							num = num % 1000000;
 							snprintf(fn, sizeof(fn), "digits/million");
 						} else {
@@ -135,9 +245,10 @@
 				}
 			}
 			if (!res) {
-				res = ast_streamfile(chan, fn, language);
-				if (!res) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+				if (full)
+				    res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
+				else
+				    res = wait_file(chan, ints, fn, language);
 				ast_stopstream(chan);
 			}
 			
@@ -146,103 +257,48 @@
 	return res;
 }
 
+static int if_say_number(int res, struct ast_channel *chan, int num, char *ints, char *lang) 
+{
+	if (res)
+	    return res;    
+	return say_number(chan, num, ints, lang, 0, 0, 0);
+}
+
+int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+{
+	return say_number(chan, num, ints, language, audiofd, ctrlfd, 1);
+}
+
 int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language)
 {
-	/* XXX Should I be merged with ast_say_number_full XXX */
-	int res = 0;
-	int playh = 0;
-	char fn[256] = "";
-	if (!num) 
-		return ast_say_digits(chan, 0,ints, language);
-	if (0) {
-	/* XXX Only works for english XXX */
-	} else {
-		/* Use english numbers */
-		language = "en";
-		while(!res && (num || playh)) {
-			if (playh) {
-				snprintf(fn, sizeof(fn), "digits/hundred");
-				playh = 0;
-			} else
-			if (num < 20) {
-				snprintf(fn, sizeof(fn), "digits/%d", num);
-				num = 0;
-			} else
-			if (num < 100) {
-				snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
-				num -= ((num / 10) * 10);
-			} else {
-				if (num < 1000){
-					snprintf(fn, sizeof(fn), "digits/%d", (num/100));
-					playh++;
-					num -= ((num / 100) * 100);
-				} else {
-					if (num < 1000000) {
-						res = ast_say_number(chan, num / 1000, ints, language);
-						if (res)
-							return res;
-						num = num % 1000;
-						snprintf(fn, sizeof(fn), "digits/thousand");
-					} else {
-						if (num < 1000000000) {
-							res = ast_say_number(chan, num / 1000000, ints, language);
-							if (res)
-								return res;
-							num = num % 1000000;
-							snprintf(fn, sizeof(fn), "digits/million");
-						} else {
-							ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
-							res = -1;
-						}
-					}
-				}
-			}
-			if (!res) {
-				res = ast_streamfile(chan, fn, language);
-				if (!res) 
-					res = ast_waitstream(chan, ints);
-				ast_stopstream(chan);
-			}
-			
-		}
-	}
-	return res;
+	return say_number(chan, num, ints, language, 0, 0, 0);
 }
+
 int ast_say_date(struct ast_channel *chan, time_t t, char *ints, char *lang)
 {
 	struct tm tm;
 	char fn[256];
 	int res = 0;
-	ast_localtime(&t,&tm,NULL);
-	if (!res) {
-		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-	}
-	if (!res) {
-		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+	localtime_r(&t,&tm);
+    	if (!strcasecmp(lang, "pt")) {
+		// PORTUGUESE
+                snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+		res = if_wait_file(res, chan, ints, fn, lang);
+            	res = if_say_number(res, chan, tm.tm_mday, ints, lang);
+		res = if_wait_file(res, chan, ints, "digits/pt-de", lang);
+                snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+		res = if_wait_file(res, chan, ints, fn, lang);
+		res = if_wait_file(res, chan, ints, "digits/pt-de", lang);
+                res = if_say_number(res, chan, tm.tm_year + 1900, ints, lang);
+        } else {
+	        // ENGLISH by default
+                snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+		res = if_wait_file(res, chan, ints, fn, lang);
+                snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+		res = if_wait_file(res, chan, ints, fn, lang);
+                res = if_say_number(res, chan, tm.tm_mday, ints, lang);
+                res = if_say_number(res, chan, tm.tm_year + 1900, ints, lang);
 	}
-	if (!res)
-		res = ast_say_number(chan, tm.tm_mday, ints, lang);
-
-	if (!res)
-		res = ast_waitstream(chan, ints);
-	if (!res)
-		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
-	return res;
-}
-
-static int wait_file(struct ast_channel *chan, char *ints, char *file, char *lang) 
-{
-	int res;
-	if ((res = ast_streamfile(chan, file, lang)))
-		ast_log(LOG_WARNING, "Unable to play message %s\n", file);
-	if (!res)
-		res = ast_waitstream(chan, ints);
 	return res;
 }
 
@@ -268,161 +324,202 @@
 				for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
 					sndfile[sndoffset] = format[offset];
 				sndfile[sndoffset] = '\0';
-				snprintf(nextmsg,sizeof(nextmsg), AST_SOUNDS "/%s", sndfile);
+				snprintf(nextmsg,sizeof(nextmsg), "%s", sndfile);
 				res = wait_file(chan,ints,nextmsg,lang);
 				break;
 			case 'A':
 			case 'a':
 				/* Sunday - Saturday */
-				snprintf(nextmsg,sizeof(nextmsg), DIGITS_DIR "day-%d", tm.tm_wday);
+				snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
 				res = wait_file(chan,ints,nextmsg,lang);
 				break;
 			case 'B':
 			case 'b':
 			case 'h':
 				/* January - December */
-				snprintf(nextmsg,sizeof(nextmsg), DIGITS_DIR "mon-%d", tm.tm_mon);
+				snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
 				res = wait_file(chan,ints,nextmsg,lang);
 				break;
 			case 'd':
 			case 'e':
-				/* First - Thirtyfirst */
-				if ((tm.tm_mday < 21) || (tm.tm_mday == 30)) {
-					snprintf(nextmsg,sizeof(nextmsg), DIGITS_DIR "h-%d", tm.tm_mday);
+			        if (!strcasecmp(lang, "pt")) {  
+				    // PORTUGUESE
+		                    res = ast_say_number(chan, tm.tm_mday, ints, lang);
+				} else {
+				    // ENGLISH by default
+				    /* First - Thirtyfirst */
+				    if ((tm.tm_mday < 21) || (tm.tm_mday == 30)) {
+					snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
 					res = wait_file(chan,ints,nextmsg,lang);
-				} else if (tm.tm_mday == 31) {
+				    } else if (tm.tm_mday == 31) {
 					/* "Thirty" and "first" */
-					res = wait_file(chan,ints,DIGITS_DIR "30",lang);
-					if (!res) {
-						res = wait_file(chan,ints,DIGITS_DIR "h-1",lang);
-					}
-				} else {
+					res = wait_file(chan,ints,"digits/30",lang);
+					res = if_wait_file(res, chan,ints,"digits/h-1",lang);
+				    } else {
 					/* Between 21 and 29 - two sounds */
-					res = wait_file(chan,ints,DIGITS_DIR "20",lang);
-					if (!res) {
-						snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "h-%d", tm.tm_mday - 20);
-						res = wait_file(chan,ints,nextmsg,lang);
-					}
+					res = wait_file(chan,ints,"digits/20",lang);
+					snprintf(nextmsg,sizeof(nextmsg),"digits/h-%d", tm.tm_mday - 20);
+					res = if_wait_file(res, chan,ints,nextmsg,lang);
+				    }
 				}
 				break;
 			case 'Y':
 				/* Year */
-				if (tm.tm_year > 99) {
-					res = wait_file(chan,ints,DIGITS_DIR "2",lang);
-					if (!res) {
-						res = wait_file(chan,ints,DIGITS_DIR "thousand",lang);
-					}
+			        if (!strcasecmp(lang, "pt")) {
+				    // PORTUGUESE
+				    res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
+				} else {
+				    // ENGLISH by default
+				    if (tm.tm_year > 99) {
+					res = wait_file(chan,ints,"digits/2",lang);
+					res = if_wait_file(res, chan,ints,"digits/thousand",lang);
 					if (tm.tm_year > 100) {
-						if (!res) {
-							/* This works until the end of 2020 */
-							snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_year - 100);
-							res = wait_file(chan,ints,nextmsg,lang);
-						}
+						/* This works until the end of 2020 */
+						snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_year - 100);
+						res = if_wait_file(res, chan,ints,nextmsg,lang);
 					}
-				} else {
+				    } else {
 					if (tm.tm_year < 1) {
 						/* I'm not going to handle 1900 and prior */
 						/* We'll just be silent on the year, instead of bombing out. */
 					} else {
-						res = wait_file(chan,ints,DIGITS_DIR "19",lang);
-						if (!res) {
-							if (tm.tm_year <= 9) {
-								/* 1901 - 1909 */
-								res = wait_file(chan,ints,DIGITS_DIR "oh",lang);
-								if (!res) {
-									snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_year);
-									res = wait_file(chan,ints,nextmsg,lang);
-								}
-							} else if (tm.tm_year <= 20) {
-								/* 1910 - 1920 */
-								snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_year);
-								res = wait_file(chan,ints,nextmsg,lang);
-							} else {
-								/* 1921 - 1999 */
-								int ten, one;
-								ten = tm.tm_year / 10;
-								one = tm.tm_year % 10;
-								snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", ten * 10);
-								res = wait_file(chan,ints,nextmsg,lang);
-								if (!res) {
-									if (one != 0) {
-										snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", one);
-										res = wait_file(chan,ints,nextmsg,lang);
-									}
-								}
+						res = wait_file(chan,ints,"digits/19",lang);
+						if (tm.tm_year <= 9) {
+							/* 1901 - 1909 */
+							res = if_wait_file(res, chan,ints,"digits/oh",lang);
+							snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_year);
+							res = if_wait_file(res, chan,ints,nextmsg,lang);
+						} else if (tm.tm_year <= 20) {
+							/* 1910 - 1920 */
+							snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_year);
+							res = if_wait_file(res, chan,ints,nextmsg,lang);
+						} else {
+							/* 1921 - 1999 */
+							int ten, one;
+							ten = tm.tm_year / 10;
+							one = tm.tm_year % 10;
+							snprintf(nextmsg,sizeof(nextmsg),"digits/%d", ten * 10);
+							res = if_wait_file(res, chan,ints,nextmsg,lang);
+							if (one != 0) {
+								snprintf(nextmsg,sizeof(nextmsg),"digits/%d", one);
+								res = if_wait_file(res, chan,ints,nextmsg,lang);
 							}
 						}
 					}
+				    }
 				}
 				break;
 			case 'I':
 			case 'l':
 				/* 12-Hour */
-				if (tm.tm_hour == 0)
-					snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "12");
-				else if (tm.tm_hour > 12)
-					snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_hour - 12);
-				else
-					snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_hour);
-				res = wait_file(chan,ints,nextmsg,lang);
+			        if (!strcasecmp(lang, "pt")) {  
+				    // PORTUGUESE
+				    if (tm.tm_hour == 0) {
+					if (format[offset] == 'I')
+					    res = wait_file(chan, ints, "digits/pt-ah", lang); 
+					res = if_wait_file(res, chan, ints, "digits/pt-meianoite", lang);
+				    } else if (tm.tm_hour == 12) {
+					if (format[offset] == 'I')
+					    res = wait_file(chan, ints, "digits/pt-ao", lang); 
+					res = if_wait_file(res, chan, ints, "digits/pt-meiodia", lang);
+				    } else {
+					if (format[offset] == 'I') {
+					    res = wait_file(chan, ints, "digits/pt-ah", lang); 
+					    if ((tm.tm_hour % 12) != 1)
+						res = if_wait_file(res, chan, ints, "digits/pt-sss", lang); 
+					}
+					res = if_say_number(res, chan, -(tm.tm_hour % 12), ints, lang);
+				    }
+				} else {
+				    // ENGLISH by default
+				    if (format[offset] == 'I')
+					res = wait_file(chan, ints, "digits/at", lang); 
+				    if (tm.tm_hour == 0)
+					snprintf(nextmsg,sizeof(nextmsg),"digits/12");
+				    else if (tm.tm_hour > 12)
+					snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_hour - 12);
+				    else
+					snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_hour);
+				    res = if_wait_file(res, chan,ints,nextmsg,lang);
+				}
 				break;
 			case 'H':
 			case 'k':
 				/* 24-Hour */
-				if (format[offset] == 'H') {
+			        if (!strcasecmp(lang, "pt")) {  
+				    // PORTUGUESE
+				    res = ast_say_number(chan, -tm.tm_hour, ints, lang);
+				} else {
+				    // ENGLISH by default
+				    if (format[offset] == 'H') {
 					/* e.g. oh-eight */
 					if (tm.tm_hour < 10) {
-						res = wait_file(chan,ints,DIGITS_DIR "oh",lang);
+						res = wait_file(chan,ints,"digits/oh",lang);
 					}
-				} else {
+				    } else {
 					/* e.g. eight */
 					if (tm.tm_hour == 0) {
-						res = wait_file(chan,ints,DIGITS_DIR "oh",lang);
-					}
-				}
-				if (!res) {
-					if (tm.tm_hour != 0) {
-						snprintf(nextmsg,sizeof(nextmsg), AST_SOUNDS "/digits/%d", tm.tm_hour);
-						res = wait_file(chan,ints,nextmsg,lang);
+						res = wait_file(chan,ints,"digits/oh",lang);
 					}
+				    }
+				    if (tm.tm_hour != 0) {
+					snprintf(nextmsg,sizeof(nextmsg), "/digits/%d", tm.tm_hour);
+					res = if_wait_file(res, chan,ints,nextmsg,lang);
+				    }
 				}
 				break;
 			case 'M':
 				/* Minute */
-				if (tm.tm_min == 0) {
-					res = wait_file(chan,ints,DIGITS_DIR "oclock",lang);
-				} else if (tm.tm_min < 10) {
-					res = wait_file(chan,ints,DIGITS_DIR "oh",lang);
-					if (!res) {
-						snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_min);
-						res = wait_file(chan,ints,nextmsg,lang);
-					}
-				} else if ((tm.tm_min < 21) || (tm.tm_min % 10 == 0)) {
-					snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", tm.tm_min);
-					res = wait_file(chan,ints,nextmsg,lang);
+			        if (!strcasecmp(lang, "pt")) {  
+				    // PORTUGUESE
+				    if (tm.tm_min == 0) {
+					res = wait_file(chan, ints, "digits/pt-hora", lang);
+		                	if (tm.tm_hour != 1)
+					    res = if_wait_file(res, chan, ints, "digits/pt-sss", lang);
+				    } else
+					res = wait_file(chan,ints,"digits/pt-e",lang);
+					res = if_say_number(res, chan, tm.tm_min, ints, lang);
 				} else {
+				    // ENGLISH by default
+				    if (tm.tm_min == 0) {
+					res = wait_file(chan,ints,"digits/oclock",lang);
+				    } else if (tm.tm_min < 10) {
+					res = wait_file(chan,ints,"digits/oh",lang);
+					snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_min);
+					res = if_wait_file(res, chan,ints,nextmsg,lang);
+				    } else if ((tm.tm_min < 21) || (tm.tm_min % 10 == 0)) {
+					snprintf(nextmsg,sizeof(nextmsg),"digits/%d", tm.tm_min);
+					res = wait_file(chan,ints,nextmsg,lang);
+				    } else {
 					int ten, one;
 					ten = (tm.tm_min / 10) * 10;
 					one = (tm.tm_min % 10);
-					snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", ten);
+					snprintf(nextmsg,sizeof(nextmsg),"digits/%d", ten);
 					res = wait_file(chan,ints,nextmsg,lang);
-					if (!res) {
-						/* Fifty, not fifty-zero */
-						if (one != 0) {
-							snprintf(nextmsg,sizeof(nextmsg),DIGITS_DIR "%d", one);
-							res = wait_file(chan,ints,nextmsg,lang);
-						}
+					/* Fifty, not fifty-zero */
+					if (one != 0) {
+						snprintf(nextmsg,sizeof(nextmsg),"digits/%d", one);
+						res = if_wait_file(res, chan,ints,nextmsg,lang);
 					}
+				    }
 				}
 				break;
 			case 'P':
 			case 'p':
 				/* AM/PM */
-				if ((tm.tm_hour == 0) || (tm.tm_hour > 11))
-					snprintf(nextmsg,sizeof(nextmsg), DIGITS_DIR "p-m");
-				else
-					snprintf(nextmsg,sizeof(nextmsg), DIGITS_DIR "a-m");
-				res = wait_file(chan,ints,nextmsg,lang);
+			        if (!strcasecmp(lang, "pt")) {  
+				    // PORTUGUESE
+				    if (tm.tm_hour > 12)
+					res = wait_file(chan, ints, "digits/p-m", lang);
+				    else if (tm.tm_hour  && tm.tm_hour < 12)
+					res = wait_file(chan, ints, "digits/a-m", lang);
+				} else {
+				    // ENGLISH by default
+				    if ((tm.tm_hour == 0) || (tm.tm_hour > 11))
+					res = wait_file(chan, ints, "digits/p-m", lang);
+				    else
+					res = wait_file(chan, ints, "digits/a-m", lang);
+				}
 				break;
 			case 'Q':
 				/* Shorthand for "Today", "Yesterday", or ABdY */
@@ -438,12 +535,18 @@
 					beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
 					if (beg_today < time) {
 						/* Today */
-						res = wait_file(chan,ints,DIGITS_DIR "today",lang);
+						res = wait_file(chan,ints,"digits/today",lang);
 					} else if (beg_today - 86400 < time) {
 						/* Yesterday */
-						res = wait_file(chan,ints,DIGITS_DIR "yesterday",lang);
+						res = wait_file(chan,ints,"digits/yesterday",lang);
 					} else {
+			    		    if (!strcasecmp(lang, "pt")) {  
+					    // PORTUGUESE
+						res = ast_say_date_with_format(chan, time, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", timezone);
+					    } else {
+					    // ENGLISH by default
 						res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
+					    }
 					}
 				}
 				break;
@@ -463,17 +566,29 @@
 						/* Today */
 					} else if ((beg_today - 86400) < time) {
 						/* Yesterday */
-						res = wait_file(chan,ints,DIGITS_DIR "yesterday",lang);
+						res = wait_file(chan,ints,"digits/yesterday",lang);
 					} else if (beg_today - 86400 * 6 < time) {
 						/* Within the last week */
 						res = ast_say_date_with_format(chan, time, ints, lang, "A", timezone);
 					} else {
+			    		    if (!strcasecmp(lang, "pt")) {  
+					    // PORTUGUESE
+						res = ast_say_date_with_format(chan, time, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", timezone);
+					    } else {
+					    // ENGLISH by default
 						res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
+					    }
 					}
 				}
 				break;
 			case 'R':
-				res = ast_say_date_with_format(chan, time, ints, lang, "HM", timezone);
+			    	if (!strcasecmp(lang, "pt")) {  
+				    // PORTUGUESE
+				    res = ast_say_date_with_format(chan, time, ints, lang, "H 'digits/pt-e' M", timezone);
+				} else {
+				    // ENGLISH by default
+				    res = ast_say_date_with_format(chan, time, ints, lang, "HM", timezone);
+				}
 				break;
 			case ' ':
 			case '	':
@@ -497,107 +612,58 @@
 	int res = 0;
 	int hour, pm=0;
 	localtime_r(&t,&tm);
-	hour = tm.tm_hour;
-	if (!hour)
+        if (!strcasecmp(lang, "pt")) {
+	    // PORTUGUESE
+    	    res = if_say_number(res, chan, -tm.tm_hour, ints, lang);
+            if (tm.tm_min) {
+		res = if_wait_file(res, chan, ints, "digits/pt-e", lang);
+            	res = if_say_number(res, chan, tm.tm_min, ints, lang);
+            } else {
+		res = if_wait_file(res, chan, ints, "digits/pt-hora", lang);
+                if (tm.tm_hour != 1)
+		    res = if_wait_file(res, chan, ints, "digits/pt-sss", lang);
+            }
+        } else {
+	    // ENGLISH by default
+            hour = tm.tm_hour;
+            if (!hour)
 		hour = 12;
-	else if (hour == 12)
+	    else if (hour == 12)
 		pm = 1;
-	else if (hour > 12) {
+	    else if (hour > 12) {
 		hour -= 12;
 		pm = 1;
-	}
-	if (!res)
-		res = ast_say_number(chan, hour, ints, lang);
+            }
+	    res = if_say_number(res, chan, hour, ints, lang);
 
-	if (tm.tm_min > 9) {
-		if (!res)
-			res = ast_say_number(chan, tm.tm_min, ints, lang);
-	} else if (tm.tm_min) {
-		if (!res)
-			res = ast_streamfile(chan, "digits/oh", lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-		if (!res)
-			res = ast_say_number(chan, tm.tm_min, ints, lang);
-	} else {
-		if (!res)
-			res = ast_streamfile(chan, "digits/oclock", lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+    	    if (tm.tm_min > 9) {
+            	res = if_say_number(res, chan, tm.tm_min, ints, lang);
+    	    } else if (tm.tm_min) {
+		res = if_wait_file(res, chan, ints, "digits/oh", lang);
+                res = if_say_number(res, chan, tm.tm_min, ints, lang);
+	    } else
+		res = if_wait_file(res, chan, ints, "digits/oclock", lang);
+
+	    if (pm)
+		res = if_wait_file(res, chan, ints, "digits/p-m", lang);
+	    else
+		res = if_wait_file(res, chan, ints, "digits/a-m", lang);
 	}
-	if (pm) {
-		if (!res)
-			res = ast_streamfile(chan, "digits/p-m", lang);
-	} else {
-		if (!res)
-			res = ast_streamfile(chan, "digits/a-m", lang);
-	}
-	if (!res)
-		res = ast_waitstream(chan, ints);
 	return res;
 }
 
-int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
+static int if_say_time(int res, struct ast_channel *chan, time_t t, char *ints, char *lang)
 {
-	struct tm tm;
-	char fn[256];
-	int res = 0;
-	int hour, pm=0;
-	localtime_r(&t,&tm);
-	if (!res) {
-		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-	}
-	if (!res) {
-		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-	}
-	if (!res)
-		res = ast_say_number(chan, tm.tm_mday, ints, lang);
-
-	hour = tm.tm_hour;
-	if (!hour)
-		hour = 12;
-	else if (hour == 12)
-		pm = 1;
-	else if (hour > 12) {
-		hour -= 12;
-		pm = 1;
-	}
-	if (!res)
-		res = ast_say_number(chan, hour, ints, lang);
+	if (res)
+	    return res;    
+	return ast_say_time(chan, t, ints, lang);
+}
 
-	if (tm.tm_min > 9) {
-		if (!res)
-			res = ast_say_number(chan, tm.tm_min, ints, lang);
-	} else if (tm.tm_min) {
-		if (!res)
-			res = ast_streamfile(chan, "digits/oh", lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-		if (!res)
-			res = ast_say_number(chan, tm.tm_min, ints, lang);
-	} else {
-		if (!res)
-			res = ast_streamfile(chan, "digits/oclock", lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-	}
-	if (pm) {
-		if (!res)
-			res = ast_streamfile(chan, "digits/p-m", lang);
-	} else {
-		if (!res)
-			res = ast_streamfile(chan, "digits/a-m", lang);
-	}
-	if (!res)
-		res = ast_waitstream(chan, ints);
-	if (!res)
-		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
+int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
+{
+	int res;
+        res = ast_say_date(chan, t, ints, lang);
+        res = if_say_time(res, chan, t, ints, lang);
 	return res;
 }
 
@@ -615,28 +681,39 @@
 	localtime_r(&t,&tm);
 	localtime_r(&nowt,&now);
 	daydiff = now.tm_yday - tm.tm_yday;
-	if ((daydiff < 0) || (daydiff > 6)) {
+        if (!strcasecmp(lang, "pt")) {  
+	    // PORTUGUESE
+            if ((daydiff < 0) || (daydiff > 6)) {
+                // Day of month and month
+                res = if_say_number(res, chan, tm.tm_mday, ints, lang);
+		res = if_wait_file(res, chan, ints, "digits/pt-de", lang);
+                snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+		res = if_wait_file(res, chan, ints, fn, lang);
+            } else if (daydiff) {
+                // Just what day of the week
+                snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+		res = if_wait_file(res, chan, ints, fn, lang);
+            }   // Otherwise, it was today
+    	    snprintf(fn, sizeof(fn), "digits/pt-ah");
+	    res = if_wait_file(res, chan, ints, fn, lang);
+            if (tm.tm_hour != 1)
+		res = if_wait_file(res, chan, ints, "digits/pt-sss", lang);
+            res = if_say_time(res, chan, t, ints, lang);
+        } else {
+	    // ENGLISH by default
+            if ((daydiff < 0) || (daydiff > 6)) {
 		/* Day of month and month */
-		if (!res) {
-			snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-			res = ast_streamfile(chan, fn, lang);
-			if (!res)
-				res = ast_waitstream(chan, ints);
-		}
-		if (!res)
-			res = ast_say_number(chan, tm.tm_mday, ints, lang);
+		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+		res = if_wait_file(res, chan, ints, fn, lang);
+		res = if_say_number(res, chan, tm.tm_mday, ints, lang);
 
-	} else if (daydiff) {
+	    } else if (daydiff) {
 		/* Just what day of the week */
-		if (!res) {
-			snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-			res = ast_streamfile(chan, fn, lang);
-			if (!res)
-				res = ast_waitstream(chan, ints);
-		}
-	} /* Otherwise, it was today */
-	if (!res)
-		res = ast_say_time(chan, t, ints, lang);
+		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+		res = if_wait_file(res, chan, ints, fn, lang);
+	    } /* Otherwise, it was today */
+	    res = if_say_time(res, chan, t, ints, lang);
+	}
 	return res;
 }
 
