const files=MODULE("https_modules/Hfiles");
const imagesize = require('image-size');
const im = require('imagemagick');
exports.Hfiles=files;

const fsi = files.fs;


// --------------------------------------cant run
load_image =  async function (name){
    return await new  Promise(async(resolve, reject) => {
        let output={};
        try{
            output.status=200;
            output.data=fsi.createReadStream(name);
        }catch(err){
            output.status=404;
            output.data=err;
        }
        resolve(output);
  });
};

/*
<define>
    #subtarget ===> نام سایر زیر پوشه ها
    #name      ===> نام فایل
    #ext       ===> پسوند فایل
    #file = PATH.public('images/#subtarget/#name.#ext');
    #color   - Example ==> "red" or "#ffdc34"
    #int+    :("0" .... infinit)
    #int50    :("1" .... 50)
    #int50+    :("0" .... 50)
    #int100    :("1" .... 100)
    #int     :("1" .... infinit)
    #text     - Example ==> "www.https-co.com"
    #position : ("north"|"northeast"|"northwest"|"south"|"southeast"|"southwest"|"east"|"west","center") 


    source   - Example ==> PATH.public('images/subfolder/start.jpg') 
    target   - Example ==> PATH.public('images/subfolder/finaly.jpg') \\ !important
    \!      important
    \~      neccesery
    /<<       start selection
    >>/       end selection

</define>
*/
/////////////////////////////////////////// resize
/*<summary>
    <name> resizingforce </name>
    <inputs>
    (source, target, width, height)
        source (#file) \!
        target (#file) \!
        width  (#int)  \! if width<0(ore height<0) => the orginal size of file will be replaced ---- عدد خیلی گنده => سیستم به فاک میره ، چون ایمیج مجیک هنگ میکنه---- عددبزرگ مثل 90000 فایل ساخته میشود ولی هیچ چیزی در ان نوشته نمیشود (0بیت حجم دارد) ضمن اینه با کندی سیستم هم مواجه میشویم----عدد را به صورت رشته هم میپزیرد و با آن مثل اینت رفتار میکند
        height (#int)  \!
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
 */
//عکس را اجبارا به اندازه های داده شده درمی آورد
exports.resizingforce = async function (source, target, rwidth, rheight){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        var options=[source,'-resize',rwidth+'x'+rheight+"\!",target];
        let output={};
        if(chk.data){
            try{
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
        
  });
};
/*<summary>
    <name> resizingfix </name> درست عمل میکند ولی برخی مواقع با ریسایز کردن و قرار دادن فایل تارگت در پوشه مورد نظر ، پیج را بر نمیگرداند و صفحه 408 را نشان میدهد
    <inputs>
    (source, target, width, height)
        source (#file) \!
        target (#file) \!
        width  (#int)  \! اگر هم طول و هم ارتفاع داده شود ، بر اساس کمترین مقدار تنظیم میکند یعنی اگر ارتفاع کمتر از طول باشد بر اساس آن تنظیم میشود--- مقدار 0 برای هریک نتیجه را به یک فایل 1*1 تبدیل میکند --- باید هم طول و هم ارتفاع داده شود وگرنه تابع اجرا نمیشود --- اگر بخواهیم بر اساس طول تنظیم کند ارتفاع را منفی یک میدهیم و برعکس --- اگر به طول منفی بدهیم و ارتفاع را وارد کنیم ابعاد اورجینال را جایگزین میکند ، اگر به ارتفاع منفی بدهیم و طول را عدد بزرگتر از 0 بگزاریم بر اساس طول تنظیم میکند ، اگر بخواهیم بر اساس ارتفاع تنظیم کنیم باید طول را بیشتر از ارتفاع قرار بدهیم تا بر اساس ارتفاع ریسایز کند 
        height (#int)  \! 
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
 */
//عکس را در یک کادر اجباری بر اساس پهنا یا ارتفاع بصورت متناسب   تغییر اندازه میدهد
exports.resizingfix = async function (source, target, rwidth, rheight){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-resize',rwidth+'x'+rheight,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
  });
};
/*<summary>
    <name> resizingH </name>
    <inputs>
    (source, target, width, height)
        source (#file) \!
        target (#file) \!
        height (#int)  \! تا 8000 پیکسل را فشار زیاد بر روی دیسک اجرا میکند ولی سیستم کند میشود ---- عدد به صورت رشته را خودش به عدد کانورت میکند --- مقدار صفر را یک فایل 1*1 بر میگرداند  -- مقدار منفی را با سایز اورجینال فایل جایگزین میکند
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
 */
//تغییر اندازه متناسب براساس ارتفاع
exports.resizingH = async function (source, target, rheight){
    const dim = imagesize(source);
    const rwidth = dim.width*rheight/dim.height;
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-resize',rwidth+'x'+rheight,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
  });
};
/*<summary>
    <name> resizingW </name>
    <inputs>
    (source, target, width, height)
        source (#file) \!
        target (#file) \!
        width  (#int)  \! مانند resizingH
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
 */
//تغییر اندازه متناسب براساس پهنا
exports.resizingW = async function (source, target, rwidth){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-resize',rwidth,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
  });
};
////////////////////////////////////////// crop
/*<summary>
    <name> croping </name>
    <inputs>
     (source, target, width, height,left,top)
        source (#file) \! 
        target (#file) \!
        width  (#int)  \!  ابعاد را به صورت درصدی هم میپذیرد منتهی باید مقدار به صورت رشته وارد شود و برای مشخص شدن درصد باید از علامت درصد استفاده شود --- اگر مقادیر منفی باشد ابعاد اورجینال جایگزین میشود --- اگر هریک از مقادیر طول یا ارتفاع منفی باشد با مقدار اورجینال خود جایگزین میشود 
        height (#int)  \! در خط بالا گفته شد 
        left (#int+)   \! اگر مقدار منفی باشد از طول یا ارتفاع کم میشود ، لفت از طول و تاپ از ارتفاع ، اگر مقدار منفی آنقدر بزرگ شود که کل طول یا ارتفاع حذف شود ابعاد فایل 1*1 میشود --- درمورد مقادیر و غیره مانند خط بالا هستند ولی مقادیر درصدی نمیپذیرند
        top (#int+)    \!   مشابه خط بالا
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
 */
//تغییر اندازه متناسب براساس ارتفاع
exports.croping = async function (source, target, cwidth, cheight,cleft,ctop){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-crop',cwidth+'x'+cheight+'+'+cleft+'+'+ctop,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
  });
};
////////////////////////////////////////// border
/*<summary>
    <name> bordering </name>
    <inputs>
        (source, target,color, xpadd,ypadd)
        source (#file)  \!
        target (#file)  \!
        width  (#int)   \!
        color  (#color) \~  ==> Default : "black"  مقدار هگز و آرجیبی ای ، هم میپذیرد
        xpadd  (#int+)  \~  ==> Default : 5     پهنای از چپ و راست  ---- مقدار منفی با حد اکثر مقدار پهنای ممکن برابری میکند مقدار درصدی میپذیرد 
        ypadd  (#int+)  \~  ==> Default : 5     پهنا از بالا و پایین --- مانند توضیح بالا
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
 */
//ایجاد خط پهن در اطراف
exports.bordering = async function (source, target, color="black", xpadd=5,ypadd=5){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-bordercolor',color, '-border',xpadd+'x'+ypadd,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
  });
};
////////////////////////////////////////// frame
/*<summary>
    <name> frameing </name>
    <inputs>
        (source, target, color, width, height,outside,inside)
        source   (#file)  \!
        target   (#file)  \!
        width    (#int)   \!
        color    (#color) \~  ==> Default : "gray"
        width    (#int)   \~  ==> Default : 7     پهنای از چپ و راست  -- پهنا های خارجی باید نصف کوچک ترین پهنای داخلی باشند --- مقدار منفی  نمیپذیرند
        height   (#int)   \~  ==> Default : 7     پهنا از بالا و پایین  
        outside  (#int)   \~  ==> Default : 2     پهنا لبه خارجی  
        inside   (#int)   \~  ==> Default : 2     پهنا لیه داخلی 
   </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
*/
//ایجاد کادر دور بهمراه تورفتگی
exports.frameing = async function (source, target, color="gray", fwidth=7, fheight=7,foutside=2,finside=2){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-mattecolor',color, '-frame',fwidth+'x'+fheight+'+'+foutside+'+'+finside,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            // output.data="File not found<br/>"+err;
            reject(output);
        }



        // if(chk.data){
        //     try{
        //         output.status=200;
        //         output.data=im.convert();
        //         // output.data=im.convert([source,'-resize',width+"x"+height,target]);
        //     }catch(err){
        //         output.status=500;
        //         output.data=err;
        //     }
        // }else{
        //     output.status=404;
        //     output.data="File not found";
        // }
        // resolve(output);
  });
};
/*<summary>
    <name> frameingPRO </name>

    <inputs>
        (source, target, args)
        source   (#file)  \!
        target   (#file)  \!
        args=[
             #color \!
            ,{
                width:(#int)    \! 
                ,height:(#int)  \! 
                ,outside:(#int) \! 
                ,inside:(#int)  \! 
            } 
            /<<
                #color \!
               ,{
                    width:(#int)    \! 
                   ,height:(#int)  \! 
                   ,outside:(#int) \! 
                   ,inside:(#int)  \! 
              } 
            >>\
             /<<
                #color \!
               ,{
                    width:(#int)    \! 
                   ,height:(#int)  \! 
                   ,outside:(#int) \! 
                   ,inside:(#int)  \! 
              } 
            >>\
            .
            .
            .
            .
        ]
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
*/
//ایجاد کادر دور بهمراه تورفتگی با تکرار به میزان دلخواه
exports.frameingPRO = async function (source, target, args){    // عدم موفقیت در نحوه ی پیاده سازی 
    var option=[];
    var cont;
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                options[0]=source;
                args.forEach((element,key) => {
                    cont=(key+1)*4;
                    options[cont-3]="-mattecolor";
                    options[cont-2]=element[0];
                    options[cont-1]="-frame";
                    options[cont]=element[1].width+'x'+element[1].height+'+'+element[1].outside+'+'+element[1].inside;
                });
                option.push(target);
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            // output.data="File not found<br/>"+err;
            reject(output);
        }





  });
};
////////////////////////////////////////// background
/*<summary>
    <name> backgrounding </name>
    <inputs>
        (source, target, color, width, height,position)
        source   (#file)  \!
        target   (#file)  \!
        width    (#int)   \!
        color    (#color) \!
        width    (#int)   \!
        height   (#int)   \!
        position (#position)   \~  ==> Default : "center"
     </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> برای 200 فایل از نوع بافر;
        output.data    ===> برای 404 پیام ارور سیستم;
    </returns> 
</summary>
*/
//ایجاد یک پس زمینه و افزایش ابعاد تصویر با رنگ مورد نظر
exports.backgrounding = async function (source, target, color, bwidth, bheight,position="center"){ // پس زمینه ای ایجاد نشد ، پزیشن هم غیر از سنتر چیزی نمیپذیرد --- اگر مقدار طول را منفی بدهیم از چپ فضای خالی ایجاد میکند با رنگ تعیین شده ---- اگر اعداد مثبت به طول و عرض دهیم از وسط به همان اندازه کات میکند
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        let output={};
        if(chk.data){
            try{
                var options=[source,'-background',color,'-gravity',position, '-extent',bwidth+'x'+bheight,target];
                await im.convert(options,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                        reject(output);
                    }else{
                        output.status=200;
                        output.data=stdout;
                        resolve(output);
                    }
                });
            }catch(err){
                output.status=500;
                output.data="تغییر اندازه ایجاد نشد<br/>"+err;
                reject(output);
            }
        }else{
            output.status=404;
            output.data="File not found<br/>"+err;
            reject(output);
        }
    });
};
////////////////////////////////////////// watermark
/*
<summary>
    <name> textWatermark </name>
        <inputs>
        (args)
        args={
            source  :(#file)  \!
            target  :(#file)  \!
            text    :(#text)  \!
            /<<
            text_position       :(#position) ==> Default : "center"
            font_lang           :("fa"|"en")       ==> Default : "en"
            font_strokewidth    :(#int)       ==> Default : "1"]
            font_strokecolor    :(#color)     ==> Default : "black"
            font_color          :(#color)     ==> Default : "white"
            font_family         :("Tahoma"|"Arial"|....)  ==> Default : "Tahoma"
            font_size           :(#int)       ==> Default : "14"
            font_boxcolor       :(#color)     ==> Default : "transparent"
            font_boxWidth       :(#int)       ==> Default : "300"
            font_boxHeight      :(#int)       ==> Default : "80"
            font_position_inbox :(#position) ==> Default : "center"
            paddLR          :(#int)   ==> Default : "0"
            padUD           :(#int)   ==> Default : "0"
            brigthness      :(#int100)       ==> Default : "15"
            saturation      :(#int100)       ==> Default : "100"
            overmethod      :("screen"|"multiply"|"modulate") ==> Default : "modulate"
            >>/
        }
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> ر;
        output.data    ===> ب;
    </returns> 
</summary>
 */
exports.textWatermark = async function (args){   //font_lang is not defined ERRORE
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        var defaults={text_position:"center",font_strokewidth:"1",font_strokecolor:"black",font_color:"white",font_family:"Tahoma",font_size:"14",font_boxcolor:"transparent",font_boxWidth:"300",font_boxHeight:"80",font_position_inbox:"center",font_lang:"en",paddLR:"+0",padUD:"+0",brigthness:15,saturation:20,overmethod:'modulate'};
        var params=Object.assign(defaults, args);
        var options = [args.source,'-strokewidth','','-stroke','','-background','','-fill','','-font', '','-pointsize','','-gravity','','-size','', '','-gravity','','-geometry','','-define','','-compose','','-composite',args.target];
        options[2]=params.font_strokewidth;
        options[4]=params.font_strokecolor;
        options[8]=params.font_color;
        options[6]=params.font_boxcolor;
        options[10]=params.font_family;
        options[12]=params.font_size;
        options[14]=params.font_position_inbox;
        options[16]=params.font_boxWidth+"x"+params.font_boxHeight;
        var label="caption:"
        if(font_lang=="fa"){label="pango:";}
        options[17]=label+unescape(params.text);
        options[19]=params.text_position;
        options[21]=""+params.paddLR+params.padUD;
        options[23]='compose:args='+params.brigthness+','+params.saturation;
        options[25]=params.overmethod;
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(options);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};

/*
<summary>
    <name> imageWatermark </name>
    <inputs>
        (args)
        args={
            source           :(#file)  \!
            watermarkimage   :(#file)  \!
            target           :(#file)  \!
            /<<
            position       :(#position) ==> Default : "center"]  تنها سنتر را قبول میکند
            paddLR          :(#int)   ==> Default : "0"]  --- اگر با + یا - نیایند تمام صفحه میشوند
            padUD           :(#int)   ==> Default : "0"] -- مانند بالا
            brigthness      :(#int100)       ==> Default : "15"] -- روشنایی عکس است --- که منفی ان روشن و مثبت ان تیره میکند--- درصد هم میپذیرد
            saturation      :(#int100)       ==> Default : "100"]  --درصد هم میپذیرد--- میزان اشباع را تعیین میکند --- مقدار منفی هم میپذیرد --- هرچه منفی تر گرم تر و هر چه مثبت تر سرد تر میشود 
            overmethod      :("screen"|"multiply"|"modulate") ==> Default : "modulate"
            >>/
        }
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> ر;
        output.data    ===> ب;
    </returns> 
</summary>
 */
exports.imageWatermark = async function (args){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        var defaults={position:'center',padLR:"+0",padUD:"+0",brigthness:15,saturation:20,overmethod:'modulate'};
        var params=Object.assign(defaults, args);
        var options=[args.source,args.watermarkimage,'-gravity','','-geometry','','-define','','-compose','','-composite',args.target];
        options[3]=params.position;
        options[5]=""+params.padLR+params.padUD;
        options[7]='compose:args='+params.brigthness+','+params.saturation;
        options[9]=params.overmethod;
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(options);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};
////////////////////////////////////////// overlay
/*
<summary>
    <name> TextOnImage </name>
    <inputs>
        (args)
        args={
            source  :(#file)  \!
            target  :(#file)  \!
            text    :(#text)  \!
            /<<
            text_position       :(#position) ==> Default : "southwest"
            font_lang           :("fa"|"en")       ==> Default : "fa"
            font_strokewidth    :(#int+)       ==> Default : "1"]  --- چه منفی و چه مثبت اتفاق خاصی نیفتاد
            font_strokecolor    :(#color)     ==> Default : "black" 
            font_color          :(#color)     ==> Default : "white" تمامی رنگ ها را میپذیرد
            font_family         :("Tahoma"|"Arial"|....)  ==> Default : "Tahoma"
            font_size           :(#int)       ==> Default : "14" -- سایز باید طوری تنظیم شود که درون فونت باکس بیفتد
            font_boxcolor       :(#color)     ==> Default : "transparent" تمامی رنگ ها را میپذیرد
            font_boxWidth       :(#int)       ==> Default : "300"
            font_boxHeight      :(#int)       ==> Default : "80"
            font_position_inbox :(#position) ==> Default : "center"
            >>/
        }
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> ر;
        output.data    ===> ب;
    </returns> 
</summary>
 */
exports.TextOnImage = async function (args){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        var defaults={text_position:"southwest",font_strokewidth:"1",font_strokecolor:"black",font_color:"white",font_family:"Tahoma",font_size:"18",font_boxcolor:"transparent",font_boxWidth:"300",font_boxHeight:"80",font_position_inbox:"center",font_lang:"fa"};
        var params=Object.assign(defaults, args);
        var options = ['-strokewidth','','-stroke','','-background','','-fill','','-font','','-pointsize','','-gravity','','-size','','',args.source,'+swap','-gravity','','-size','100x','-composite',args.target];
        options[1]=params.font_strokewidth;
        options[3]=params.font_strokecolor;
        options[7]=params.font_color;
        options[5]=params.font_boxcolor;
        options[9]=params.font_family;
        options[11]=params.font_size;
        options[13]=params.font_position_inbox;
        options[15]=params.font_boxWidth+"x"+params.font_boxHeight;
        var label="pango:";
        if(params.font_lang=="en"){label="caption:";}
        options[16]=label+unescape(params.text);
        options[20]=params.text_position;
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(options);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};
////////////////////////////////////// card
/*
<summary>
    <name> card </name>
    <inputs>
        (args)
        args={
            source  :(#file)  \!
            target  :(#file)  \!
            text    :(#text)  \!
            /<<
            frameColor       :(#color)     ==> Default : "gray"
            topdownMargin    :(#int)       ==> Default : 5 
            sideMargin       :(#int)       ==> Default : 5
            internalSlop     :(#int)       ==> Default : 2 مقدار منفی هم قبول میکنند اما اصلا منطقی نیست 
            externalSlop     :(#int)       ==> Default : 2 مقدار منفی هم قبول میکنند اما اصلا منطقی نیست 
            font_lang           :("fa"|"en")       ==> Default : "fa"
            font_strokewidth    :(#int+)       ==> Default : "1"]
            font_strokecolor    :(#color)     ==> Default : "black"
            font_color          :(#color)     ==> Default : "black"
            font_family         :("Tahoma"|"Arial"|....)  ==> Default : "Mitra"
            font_size           :(#int)       ==> Default : "14"
            font_boxcolor       :(#color)     ==> Default : "transparent"
            text_location       :("left"|"right"|"center") ==> Default : "right"
            >>/
        }
    </inputs>
    <returns>
        output ===> object type
        output.status ===> 200 برای اجرای درست;
        output.status ===> 500 برای اجرای نادرست;
        output.status ===> 404 فایل یافت نشد;
        output.data    ===> ر;
        output.data    ===> ب;
    </returns> 
</summary>
 */
exports.card = async function (args){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        const dim = imagesize(args.source);
        let output={};
        var defaults={frameColor:"gray",topdownMargin:5,sideMargin:15,internalSlop:2,externalSlop:2,font_strokewidth:"0",font_strokecolor:"black",font_color:"black",font_boxcolor:"transparent",font_family:'Mitra',font_size:"14",font_boxWidth:"300",font_boxHeight:"80",text_location:"right",font_lang:"fa"};
        var params=Object.assign(defaults, args);
        var options1=[args.source,'-mattecolor','', '-frame','','-background',"",'-gravity',"north", '-extent','','-mattecolor','', '-frame','',args.target];
        
        var lineNum=args.text.match(/\n/g); // اگر متن تک خطی بود ارور میداد بنابر این طبق الگوی جدید اصلاح شد
        if(lineNum == null){lineNum=[];}
        lineNum=lineNum.length;
        //-----------------------------------------------------------------
        options1[2]=params.frameColor;
        options1[6]=params.frameColor;
        options1[12]=params.frameColor;
        options1[4]=params.internalSlop+'x'+params.internalSlop+'+0+'+params.internalSlop;
        options1[10]=dim.width+'x'+((params.internalSlop*2)+params.topdownMargin+(params.font_size*2*lineNum)+dim.height);
        options1[14]=(params.sideMargin+params.externalSlop)+'x'+(params.topdownMargin+params.externalSlop)+'+'+params.externalSlop+'+0';
    //     var options1=[source,'-mattecolor','','-frame','','-background',"",'-gravity',"north", '-extent','','-mattecolor','', '-frame','',target];
        var options2 = ['-strokewidth','','-stroke','','-background','','-fill','','-font','','-pointsize','','-gravity','','-size','','',args.target,'+swap','-gravity','South','-geometry','','-size','100x','-composite',args.target];
        options2[1]=params.font_strokewidth;
        options2[3]=params.font_strokecolor;
        options2[7]=params.font_color;
        options2[5]=params.font_boxcolor;
        options2[9]=params.font_family;
        options2[11]=params.font_size;
        var gravity='',label="pango:";
        switch(params.text_location){
            case "left":
                gravity='east';
                break;
            case "center":
                gravity='center';
                break;
            default:
                gravity='west';
                break;
                
        }
        if(params.font_lang=="en"){label="caption:";}
        options2[13]=gravity;
        options2[15]=dim.width+"x"+(params.font_size*2*lineNum);
        options2[16]=label+unescape(args.text);
        options2[22]='+0+'+(params.topdownMargin+params.externalSlop);

    //var options1=[source,'-mattecolor','red', '-frame','15x2+0+2','-background',"brown",'-gravity',"north", '-extent',(rwidth+50)+'x530','-mattecolor','blue', '-frame','25x7+2+0',target];
//    var options1=[source,'-background',"red",'-gravity',"north", '-extent','1000x490',target];
//var options2 = ['-strokewidth','2','-stroke','brown','-background','white','-fill','green','-font','Mitra','-pointsize','30','-gravity','west','-size','400x60','pango:این یک متن آزمایشیست  دایره',target,'+swap','-gravity','south','-geometry','+0+0','-size','100x','-composite',target];
//output.data=im.convert(['-strokewidth','2','-stroke','brown','-background','white','-fill','green','-font','Mitra','-pointsize','40','-gravity','west','-size','400x80','pango:این یک متن آزمایشیست  دایره',target,'+swap','-gravity','south','-geometry','+15+20','-size','100x','-composite',target2]);
      
        if(chk.data){
            try{
                
                await im.convert(options1,async (err,stdout)=>{
                    if(err){
                        output.status=500;
                        output.data="cant make frame";
                        resolve(output);
                    }else{
                        await im.convert(options2,(err)=>{
                            if(err){
                                output.status=500;
                                output.data="make fram but text not write";
                                resolve(output);

                            }else{
                                output.status=200;
                                output.data=stdout;
                                resolve(output);

                            }
       
                        });
                    }
                   
                });
                
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
                resolve(output);

            }
        }else{
            output.status=404;
            output.data="File not found";
            resolve(output);

        }
  });
};
//////////////////////////////////////////////  comming soon
exports.TextpattImage = async function (args){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        var defaults={text_position:"southwest",font_strokewidth:"1",font_strokecolor:"black",font_color:"white",font_family:"Tahoma",font_size:"14",font_boxcolor:"transparent",font_boxWidth:"300",font_boxHeight:"80",font_position_inbox:"center",font_lang:"en"};
        var params=Object.assign(defaults, args);

        var options = ['-strokewidth','','-stroke','','-background','','-fill','','-font','','-pointsize','','-gravity','','-size','','',args.source,'+swap','-gravity','','-size','100x','-composite',args.target];
        options[1]=params.font_strokewidth;
        options[3]=params.font_strokecolor;
        options[7]=params.font_color;
        options[5]=params.font_boxcolor;
        options[9]=params.font_family;
        options[11]=params.font_size;
        options[13]=params.font_position_inbox;
        options[15]=params.font_boxWidth+"x"+params.font_boxHeight;
        var label="caption:"
        if(params.font_lang=="fa"){label="pango:";}
        options[16]=label+unescape(params.text);
        options[20]=params.text_position;

//        var opt=[ '-strokewidth','2','-stroke','red','-background' ,'blue' ,'-font', 'Arial', '-pointsize', '20' ,'-fill', 'grey','-gravity','center','-size','900x450','label:This is very long long long long long long long long label.', '-rotate', '-45','-write' ,'mpr:tile', '+delete', '+clone', '-tile', 'mpr:tile',args.source,'+swap','-gravity','center','-size','100x','-compose' ,'over', '-composite',args.target];
//var opt=[ '-strokewidth','2','-stroke','red','-background' ,'blue' ,'-font', 'Arial', '-pointsize', '20' ,'-fill', 'grey','-gravity','center','label:This is very long long long long long long long long label.', '-rotate', '-45', '-tile', '2x2',args.source,'+swap','-gravity','center','-size','100x','-compose' ,'over', '-composite',args.target];
var opt=['-size','300x300','-scale','400%','pattern:CrossHatch30',args.target];

// D:\tile.jpg -resize 300x300 -write mpr:tiler +delete ^
//    -size 900x900 tile:mpr:tiler -sharpen 0x2 D:\tiles.jpg
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(opt);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};
///////////////////////////// color replacment   
exports.colorReplace = async function (args){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        var defaults={text_position:"southwest",font_strokewidth:"1",font_strokecolor:"black",font_color:"white",font_family:"Tahoma",font_size:"14",font_boxcolor:"transparent",font_boxWidth:"300",font_boxHeight:"80",font_position_inbox:"center",font_lang:"en"};
        var params=Object.assign(defaults, args);
        var options = [args.source,'-matte','-fuzz','15%','-transparent','green',args.target];//
        var options = [args.source,'-fill','blur','-opaque','black',args.target];
        // options[1]=params.font_strokewidth;
        // options[3]=params.font_strokecolor;
        // options[7]=params.font_color;
        // options[5]=params.font_boxcolor;
        // options[9]=params.font_family;
        // options[11]=params.font_size;
        // options[13]=params.font_position_inbox;
        // options[15]=params.font_boxWidth+"x"+params.font_boxHeight;
        // var label="caption:"
        // if(params.font_lang=="fa"){label="pango:";}
        // options[16]=label+unescape(params.text);
        // options[20]=params.text_position;
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(options);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};
exports.TextRotateOnImage = async function (args){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(args.source);
        var defaults={text_position:"southwest",font_strokewidth:"1",font_strokecolor:"black",font_color:"white",font_family:"Tahoma",font_size:"14",font_boxcolor:"transparent",font_boxWidth:"300",font_boxHeight:"80",font_position_inbox:"center",font_lang:"en"};
        var params=Object.assign(defaults, args);

        var options = ['-strokewidth','','-stroke','','-background','','-fill','','-font','','-pointsize','','-gravity','','-size','','',args.source,'+swap','-gravity','','-size','100x','-composite',args.target];
        options[1]=params.font_strokewidth;
        options[3]=params.font_strokecolor;
        options[7]=params.font_color;
        options[5]=params.font_boxcolor;
        options[9]=params.font_family;
        options[11]=params.font_size;
        options[13]=params.font_position_inbox;
        options[15]=params.font_boxWidth+"x"+params.font_boxHeight;
        var label="caption:"
        if(params.font_lang=="fa"){label="pango:";}
        options[16]=label+unescape(params.text);
        options[20]=params.text_position;

//        var opt=[ '-strokewidth','2','-stroke','red','-background' ,'blue' ,'-font', 'Arial', '-pointsize', '20' ,'-fill', 'grey','-gravity','center','-size','900x450','label:This is very long long long long long long long long label.', '-rotate', '-45','-write' ,'mpr:tile', '+delete', '+clone', '-tile', 'mpr:tile',args.source,'+swap','-gravity','center','-size','100x','-compose' ,'over', '-composite',args.target];
//var opt=[ '-strokewidth','2','-stroke','red','-background' ,'blue' ,'-font', 'Arial', '-pointsize', '20' ,'-fill', 'grey','-gravity','center','label:This is very long long long long long long long long label.', '-rotate', '-45', '-tile', '2x2',args.source,'+swap','-gravity','center','-size','100x','-compose' ,'over', '-composite',args.target];
var opt=[ '-strokewidth','2','-stroke','red','-background' ,'blue' ,'-font', 'Arial', '-pointsize', '20' ,'-fill', 'grey','-gravity','center','-size','400x150','label:This is very long long long long long long long long 145 nbhn.', '-rotate', '-45',args.source,'+swap','-gravity','center','-size','100x','-compose' ,'over', '-composite',args.target];
// D:\tile.jpg -resize 300x300 -write mpr:tiler +delete ^
//    -size 900x900 tile:mpr:tiler -sharpen 0x2 D:\tiles.jpg
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(opt);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};
/*
app.get('/getimage/information', function(req, res) {
    im.identify(srcImage, function(err, features){
        if (err) throw err;
        res.json({"images_data": features});
    });
});
app.get('/getimage/readmetadata', function(req, res) {
    im.readMetadata(srcImage, function(err, metadata){
        if (err) throw err;
        res.json({"metadata": metadata});
    });
});
im.resize(optionsObj, callback(err, stdout))
{
    srcPath: undefined,
    srcData: null,
    srcFormat: null,
    dstPath: undefined,
    quality: 0.8,
    format: 'jpg',
    progressive: false,
    width: 0,
    height: 0,
    strip: true,
    filter: 'Lagrange',
    sharpening: 0.2,
    customArgs: []
}
app.get('/image/resize', function(req, res) {
    var optionsObj = {
        srcPath: srcImage,
        dstPath: desPath+"butterfly_lowquality.jpg",
        quality: 0.6,
        width: ""
    };
    im.resize(optionsObj, function(err, stdout){
        if (err) throw err;
        res.json({
            "message": "Resized Image successfully"
        });
    });
});

app.get('/image/crop', function(req, res) {
    var optionsObj = {
        srcPath: srcImage,
        dstPath: desPath+'butterfly_cropped.jpg',
        width: 800,
        height: 600,
        quality: 1,
        gravity: "North"
    };
    im.crop(optionsObj, function(err, stdout){
        if (err) throw err;
        res.json({
            "message": "cropped Image successfully"
        });
    });
});
*/
exports.textWatermark6 = async function (source,target){
    return await new  Promise(async(resolve, reject) => {
        var chk=await files.checkfile(source);
        // var defaults={position:'center',paddLR:"+0",padUD:"+0",brigthness:15,saturation:100,overmethod:'modulate'};
        // var params=Object.assign(defaults, args);
        // var options=["","",'-gravity','','-geometry','','-define','','-compose','','-composite',""];
        // var options=["","",'-gravity','center','-geometry','+0+0','-define','compose:args=15,100','-compose','modulate','-composite',""];
        // options[0]=params.source;
        // options[1]=params.watermarkimage;
        // options[3]=params.position;
        // options[5]=""+params.paddLR+params.padUD;
        // options[7]='compose:args='+params.brigthness+','+params.saturation;
        // options[9]=params.overmethod;
        // options[11]=params.target;
        var options = [source,'-strokewidth','1','-stroke','black','-background','transparent','-fill','white','-font', 'Tahoma','-pointsize','40','-gravity','center',  '-size','300x130', "caption:"+unescape(" : 445"),'-gravity','center','-geometry','+0+0','-define','compose:args=55,100','-compose','modulate','-composite',target];

        console.log(options);
        let output={};
        if(chk.data){
            try{
                output.status=200;
                output.data=im.convert(options);
                // output.data=im.convert([source,'-resize',width+"x"+height,target]);
            }catch(err){
                output.status=500;
                output.data="تصویر واترمارک روی تصویر مورد نظر ثبت نگردید<br/>"+err;
            }
        }else{
            output.status=404;
            output.data="File not found";
        }
        resolve(output);
  });
};

//-interword-spacing 25          -kerning -1
// composite {overlay} {background} [{mask}] [-compose {method}]   {result}
// convert  {background} {overlay} [{mask}] [-compose {method}] -composite   {result}
// -mattecolor grey  -background grey  -frame 3x3+0+3 \
//           -gravity South -splice 0x15 -annotate 0x0 'A Red Rose' \
//           -frame 6x6+3+0    frame_montage.gif
//-font Candice -pointsize 48 label:A
// magick convert -size 320x85 canvas:none -font Bookman-DemiItalic -pointsize 72 \
//   -draw "text 25,60 \'Magick\'" -channel RGBA -blur 0x6 -fill darkred -stroke magenta \
//   -draw "text 20,55 \'Magick\'" fuzzy-magick.png
// magick convert -size 320x85 canvas:none -font Bookman-DemiItalic -pointsize 72 \
//   -draw "text 25,60 \'Magick\'" -channel RGBA -blur 0x6 -fill darkred -stroke magenta \
//   -draw "text 20,55 \'Magick\'" fuzzy-magick.png
//   magick composite -gravity center smile.gif  rose: rose-over.png 
// convert -background lightblue -fill blue  -font Candice \
// -size 165x70  -pointsize 24  -gravity center \
// label:Anthony     label_gravity.gif
//convert -size 100x100 gradient:'gray(100%)-gray(0)' \ -set colorspace sRGB gradient.gif
//-colorspace HSI  -channel B -separate channel_average.gif
//convert rose:  -emboss 0x1.1 rose_emboss_0x11.gif
//-colorspace Gray  -emboss 0x1.2 rose_g_emboss_0x12.gif
//-charcoal 3   rose_charcoal_3.gif
//-blur 0x3
//-colorspace Gray  -emboss 0x1.1 rose_g_emboss_0x11.gif
// -colorspace Gray  -edge 1 -negate  piglet_edge.gif
// convert -size 8x8 pattern:CrossHatch30 -scale 800% scale_crosshatch.gif
// convert -size 150x60 xc: -draw 'line 0,59 149,0' line_orig.gif
// convert line_orig.gif  -sample 50x20  line_sample.gif
// convert rings_crop.png    -sample 100x100    rings_crop_sample.png
// convert rings_crop.png    -scale  100x100    rings_crop_scale.png




