/* persian.js  JavaScript tools for Persian computing
 * Copyright (C) 2003  Behdad Esfahbod <persianjs@behdad.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You can receive a copy of GNU Lesser General Public License at the
 * World Wide Web address <http://www.gnu.org/licenses/lgpl.html>.
 *
 * For licensing issues, contact The FarsiWeb Project Group,
 * Computing Center, Sharif University of Technology,
 * PO Box 11365-8515, Tehran, Iran, or contact us the
 * email address <FWPG@sharif.edu>.
 */

persian_digit = new Array();
for (i = 0; i < 10; i++)
  persian_digit[i] = String.fromCharCode(0x06F0 + i);

latin_digit_alpha = new Array("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine");
persian_digit_alpha = new Array("\u0635\u0641\u0631", "\u06cc\u06a9", "\u062f\u0648", "\u0633\u0647", "\u0686\u0647\u0627\u0631", "\u067e\u0646\u062c", "\u0634\u0634", "\u0647\u0641\u062a", "\u0647\u0634\u062a", "\u0646\u0647");
latin_teen_alpha = new Array("eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen");
persian_teen_alpha = new Array("\u06cc\u0627\u0632\u062f\u0647", "\u062f\u0648\u0627\u0632\u062f\u0647", "\u0633\u06cc\u0632\u062f\u0647", "\u0686\u0647\u0627\u0631\u062f\u0647", "\u067e\u0627\u0646\u0632\u062f\u0647", "\u0634\u0627\u0646\u0632\u062f\u0647", "\u0647\u0641\u062f\u0647", "\u0647\u06cc\u062c\u062f\u0647", "\u0646\u0648\u0632\u062f\u0647");
latin_tens_alpha = new Array("ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety");
persian_tens_alpha = new Array("\u062f\u0647", "\u0628\u06cc\u0633\u062a", "\u0633\u06cc", "\u0686\u0647\u0644", "\u067e\u0646\u062c\u0627\u0647", "\u0634\u0635\u062a", "\u0647\u0641\u062a\u0627\u062f", "\u0647\u0634\u062a\u0627\u062f", "\u0646\u0648\u062f");
latin_weekday_alpha = new Array("saturday", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday");
persian_weekday_alpha = new Array("\u0634\u0646\u0628\u0647", "\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647", "\u062f\u0648\u0634\u0646\u0628\u0647", "\u0633\u0647\u200c\u0634\u0646\u0628\u0647", "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647", "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647", "\u062c\u0645\u0639\u0647");
latin_jalali_month_alpha = new Array("farvardin", "ordibehesht", "khordad", "tir", "mordad", "shahrivar", "mehr", "aban", "azar", "dey", "bahman", "esfand");
persian_jalali_month_alpha = new Array("\u0641\u0631\u0648\u0631\u062f\u06cc\u0646", "\u0627\u0631\u062f\u06cc\u0628\u0647\u0634\u062a", "\u062e\u0631\u062f\u0627\u062f", "\u062a\u06cc\u0631", "\u0645\u0631\u062f\u0627\u062f", "\u0634\u0647\u0631\u06cc\u0648\u0631", "\u0645\u0647\u0631", "\u0622\u0628\u0627\u0646", "\u0622\u0630\u0631", "\u062f\u06cc", "\u0628\u0647\u0645\u0646", "\u0627\u0633\u0641\u0646\u062f");
latin_gregorian_month_alpha = new Array("january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december");
persian_gregorian_month_alpha = new Array("\u0698\u0627\u0646\u0648\u06cc\u0647", "\u0641\u0648\u0631\u06cc\u0647", "\u0645\u0627\u0631\u0633", "\u0622\u0648\u0631\u06cc\u0644", "\u0645\u0647", "\u0698\u0648\u0626\u0646", "\u0698\u0648\u0626\u06cc\u0647", "\u0627\u0648\u062a", "\u0633\u067e\u062a\u0627\u0645\u0628\u0631", "\u0627\u06a9\u062a\u0628\u0631", "\u0646\u0648\u0627\u0645\u0628\u0631", "\u062f\u0633\u0627\u0645\u0628\u0631");

persian_daytime_alpha = new Array("\u0646\u06cc\u0645\u0647\u200c\u0634\u0628", "\u0628\u0627\u0645\u062f\u0627\u062f", "\u0635\u0628\u062d", "\u0638\u0647\u0631", "\u0639\u0635\u0631", "\u0634\u0628");
persian_daytime_hours = new Array("0?0|12", "0?[1-6]", "[01]?[0-9]", "0?0|12", "0?[1-6]", "[01]?[0-9]");
persian_daytime_ampm = new Array("AM", "AM", "AM", "PM", "PM", "PM");


re_order = new Array(/(1)st/gi, /(2)nd/gi, /(3)rd/gi, /([04-9])th/gi);
ds_order = new Array("$1\u0645", "$1\u0645", "$1\u0645", "$1\u0645");

function to_persian_order(s, remove) {
  var i;
  s = String(s);
  for (i = 0; i < re_order.length; i++)
    s = s.replace(re_order[i], remove ? "$1" : ds_order[i]);
  return s;
}

re_number = new Array(/%/g, /(\d)\.(?=\d)/g); //, /(\d)\'(?=\d)/g);
ds_number = new Array("\u066A", "$1\u066B"); //, "$1\u066C");
for (i = 0; i < 10; i++) {
  re_number.push(RegExp(i, ["g"]));
  ds_number.push(persian_digit[i]);
}

function to_persian_number(s) {
  var i;
  s = String(s);
  for (i = 0; i < re_number.length; i++)
    s = s.replace(re_number[i], ds_number[i]);
  return s;
}

sr_punc = new Array(",", ";", "\\?");
ds_punc = new Array("\u060C", "\u061B", "\u061F");
re_punc = new Array();
for (i = 0; i < sr_punc.length; i++)
  re_punc[i] = RegExp(sr_punc[i], ["g"]);

function to_persian_punc(s) {
  var i;
  for (i = 0; i < re_punc.length; i++)
    s = s.replace(re_punc[i], ds_punc[i]);
  return s;
}

sr_weekday = new Array();
re_weekday = new Array();
for (i = 0; i < latin_weekday_alpha.length; i++) {
  sr_weekday[i] = "\\b(" + latin_weekday_alpha[i].slice(0, 3) + "(?:\\.?|"+ latin_weekday_alpha[i].slice(3) +"))\\b";
  re_weekday[i] = RegExp(sr_weekday[i], ["gi"]);
}

function to_persian_weekday(s) {
  var i;

  for (i = 0; i < re_weekday.length; i++)
    s = s.replace(re_weekday[i], persian_weekday_alpha[i]);
  return s;
}

sr_gmonth = new Array();
re_gmonth = new Array();
sr_gmonths = "";
for (i = 0; i < latin_gregorian_month_alpha.length; i++) {
  sr_gmonth[i] = latin_gregorian_month_alpha[i].slice(0, 3)
    + "(?:\\.?|"+ latin_gregorian_month_alpha[i].slice(3) +")";
  sr_gmonths += (i?"|":"") + sr_gmonth[i];
  sr_gmonth[i] = "\\b(" + sr_gmonth[i] + ")\\b";
  re_gmonth[i] = (RegExp(sr_gmonth[i], ["gi"]));
}
sr_gmonths = "\\b(" + sr_gmonths + ")\\b";
re_gmonths = RegExp(sr_gmonths, ["gi"]);

sr_jmonth = new Array();
re_jmonth = new Array();
for (i = 0; i < latin_jalali_month_alpha.length; i++) {
  sr_jmonth[i] = ("\\b(" + latin_jalali_month_alpha[i] +")\\b");
  re_jmonth[i] = (RegExp(sr_jmonth[i], ["gi"]));
}

function to_persian_month(s) {
  var i;

  for (i = 0; i < re_gmonth.length; i++)
    s = s.replace(re_gmonth[i], persian_gregorian_month_alpha[i]);
  for (i = 0; i < re_jmonth.length; i++)
    s = s.replace(re_jmonth[i], persian_jalali_month_alpha[i]);
  return s;
}

re_month_day = new Array();
for (i = 0; i < latin_gregorian_month_alpha.length; i++)
  re_month_day[i] = RegExp(sr_gmonth[i] +" +([0-2]?[0-9]|3[0-1])((?:st|nd|rd|th)?)\\b,?", ["gi"]);

function to_reverse_gregorian(s, remove) {
  var i;

  for (i = 0; i < re_month_day.length; i++)
    s = s.replace(re_month_day[i], "$2" + (remove?"":"$3") + " $1");
  return s;
}

re_daytime = new Array();
for (i = 0; i < persian_daytime_alpha.length; i++)
  re_daytime[i] = RegExp("([^:0-9])(("+persian_daytime_hours[i]+")(?::[0-5]?[0-9](?::[0-5]?[0-9](?:[:.]?[0-9]?[0-9])?)?)?)( *)("+persian_daytime_ampm[i]+")\\b", ["gi"]);

function to_persian_daytime(s) {
  var i;

  for (i = 0; i < re_daytime.length; i++) {
    s = " " + s;
    s = s.replace(re_daytime[i], "$1$2$4" + persian_daytime_alpha[i]);
    s = s.substr(1);
  }
  return s;
}

function to_gmonth_number(s) {
  var i;

  for (i = 0; i < re_gmonth.length; i++)
    if (s.match(re_gmonth[i]))
      return i;
  return -1;
}

function check_jalali(err) {
  if (!has_jalali && window.gregorian_to_jalali != null) {
    has_jalali = 1;
    gtoday = new Date();
    gtoday = new Array(gtoday.getFullYear(),gtoday.getMonth()+1,gtoday.getDate());
    jtoday = gregorian_to_jalali(gtoday);
    gtoday[1]--;
    jtoday[1]--;
  }
  if (!has_jalali) {
    if (err && !error_jalali) {
      document.write("Error:  You should include jalali.js to use Persian calendar.<br>".bold());
      error_jalali = 1;
    }
  }
  return has_jalali;
}

has_jalali = 0;
error_jalali = 0;
check_jalali();

sr_datenum = "([0-2]?[0-9]|3[0-1])";
sr_datenumsuf = "([0-2]?[0-9]|3[0-1])(?:st|nd|rd|th)?\\b";
sr_monthnum = "(0?[1-9]|1[0-2])"
sr_gyearnum2 = "([0-9][0-9])"
sr_gyearnum4 = "(1[6-9][0-9][0-9]|20[0-9][0-9])"
sr_separator = "(|\.|/|-)";

sr_persian_date = new Array();
re_persian_date = new Array();
de_persian_date = new Array();

sr_persian_date.push(sr_datenumsuf+" "+sr_gmonths+" "+sr_gyearnum4);
de_persian_date.push(function (s, dd, mmmm, yyyy, offset, ss) {
  var mm = to_gmonth_number(mmmm)+1;
  if (mm <= 0) return (s);
  var j = gregorian_to_jalali(new Array(yyyy, mm, dd));
  return to_persian(j[2]+" "+latin_jalali_month_alpha[j[1]-1]+" "+j[0]);
});
sr_persian_date.push(sr_datenumsuf+" "+sr_gmonths);
de_persian_date.push(function (s, dd, mmmm, offset, ss) {
  var mm = to_gmonth_number(mmmm)+1;
  if (mm <= 0) return (s);
  var j = gregorian_to_jalali(new Array(gtoday[0], mm, dd));
  return to_persian(j[2]+" "+latin_jalali_month_alpha[j[1]-1]);
});
sr_persian_date.push(sr_monthnum+sr_separator+sr_datenum+"\\2"+sr_gyearnum4);
de_persian_date.push(function (s, mm, sep, dd, yyyy, offset, ss) {
  var j = gregorian_to_jalali(new Array(yyyy, mm, dd));
  return to_persian(j[2]+sep+j[1]+sep+j[0]);
});
sr_persian_date.push(sr_gyearnum4+sr_separator+sr_monthnum+"\\2"+sr_datenum);
de_persian_date.push(function (s, yyyy, sep, mm, dd, offset, ss) {
  var j = gregorian_to_jalali(new Array(yyyy, mm, dd));
  if (sep == "" && j[1] < 10) j[1] = "0"+j[1];
  if (j[2] < 10) j[2] = "0"+j[2];
  return to_persian(j[0]+sep+j[1]+sep+j[2]);
});
sr_persian_date.push(sr_datenum+"(\\.)"+sr_monthnum+"\\2"+sr_gyearnum2);
de_persian_date.push(function (s, dd, sep, mm, yy, offset, ss) {
  var yyyy = yy*1 + (yy < 20 ? 2000 : 1900);
  var j = gregorian_to_jalali(new Array(yyyy, mm, dd));
  j[0] -= 1300;  if (j[0] > 100) j[0] -= 100;
  if (j[0] < 10) j[0] = "0"+j[0];
  if (j[2] < 10) j[2] = "0"+j[2];
  return to_persian(j[2]+sep+j[1]+sep+j[0]);
});

for (i = 0; i < sr_persian_date.length; i++)
  re_persian_date[i] = RegExp("\\b"+sr_persian_date[i]+"\\b", ["gi"]);

function to_jalali_calendar(s) {
  if (!check_jalali(1)) {
    return s;
  }

  var i;

  s = to_reverse_gregorian(s);

  for (i = 0; i < re_persian_date.length; i++)
    s = s.replace(re_persian_date[i], de_persian_date[i]);
  return s;
}

function to_persian_calendar(s) {
  return (
    to_persian_month(
      to_persian_punc(
        to_persian_weekday(
          to_persian_number(
            to_persian_order(
              to_persian_daytime(
                to_jalali_calendar(s)
              )
            )
          )
        )
      )
    )
  );
}

function to_persian(s) {
  return (
    to_persian_month(
      to_persian_punc(
        to_persian_weekday(
          to_persian_number(
            to_persian_order(
              to_persian_daytime(
                to_reverse_gregorian(s)
              )
            )
          )
        )
      )
    )
  );
}

function skip_tags(f, s) {
  return s.replace(/(^|>)((?:[^<]|<[^a-zA-Z])*)/g, function(s, p1, p2, ofs, ss) { return p1 + f(p2); });
}
