<?php

defined( 'ABSPATH' ) || exit;

foreach( array( 'image', 'audio', 'postmeta', 'post_id_info', 'multi', 'date', 'video', 'color', 'dropdown', 'dropdownbutton', 'textbox', 'textarea', 'checkbox', 'separator', 'layout', 'radio', 'gallery_shortcode', 'query_category', 'assignments', 'repeater', 'image_radio', 'hidden' ) as $field_type ) {
    add_action( "themify_metabox/field/{$field_type}", "themify_meta_field_{$field_type}", 10, 1 );
}
add_action( 'wp_ajax_themify_metabox_media_lib_browse', 'themify_metabox_media_lib_browse' );
add_action( 'wp_ajax_themify_plupload', 'themify_wp_ajax_plupload_image' );
add_action( 'wp_ajax_themify_create_inner_popup_page', 'themify_ajax_create_inner_page' );
add_action( 'wp_ajax_themify_create_popup_page_pagination', 'themify_ajax_create_page_pagination' );

function themify_meta_field_image( $args ) {
    if ( ! current_user_can( 'upload_files' ) ) {
        themify_meta_field_textbox( $args );
        return;
    }

    extract( $args, EXTR_OVERWRITE );

    /** Parameters for the uploader @var Array */
    $featimg_uploader_args = array(
        'tomedia' => true,
        'topost' => $post_id,
        'medialib' => true,
        'fields' => $meta_box['name']
    );
    ?>

    <div class="themify_clear_field <?php if( $meta_value == '' ) echo 'hide' ?>">
        <a href="#"><?php _e( 'Remove image', 'themify' ); ?></a>
    </div>

    <?php
    if( $meta_value ) {
        echo '
        <div class="themify_upload_preview" style="display:block;">
            <a href="' . esc_url( $meta_value ) . '" target="_blank">
                <img src="' . esc_url( $meta_value ) . '" style="width: 40px; height: 40px;" alt="' . esc_attr__( 'Post Image', 'themify' ) . '" />
            </a>
        </div>';
    } else {
        echo '<div class="themify_upload_preview"></div>';
    }
    ?>

    <!-- Field storing URL -->
    <input type="hidden" id="<?php echo esc_attr( $meta_box['name'] ); ?>" name="<?php echo esc_attr( $meta_box['name'] ); ?>" value="<?php echo esc_attr( $meta_value ); ?>" size="55" class="themify_input_field themify_upload_field" />

    <div class="themify_upload_buttons">
        <?php themify_uploader($meta_box['name'], $featimg_uploader_args) ?>
    </div>

    <?php if ( isset( $meta_box['description'] ) ) : ?>
        <span class="themify_field_description"><?php echo wp_kses_post( $meta_box['description'] ); ?></span>
    <?php endif; // meta_box description
}

function themify_meta_field_font( $args ) {
    $meta_box = $args['meta_box'];
    $sanitized_name = sanitize_html_class( $meta_box['name'] );
    extract( $args, EXTR_OVERWRITE );

    /** Parameters for the uploader @var Array */
    $featimg_uploader_args = array(
        'tomedia'   => true,
        'topost'    => $post_id,
        'medialib'  => true,
        'fields'    => $sanitized_name,
        'formats'   => $meta_box['ext'],
        'type'      => 'font',
    );

    $remove_data = array(
        'postid'        => esc_js( $post_id ),
        'customfield'   => esc_js( $meta_box['name'] ),
        'nonce'         => esc_js( $themify_custom_panel_nonce )
    ); ?>

    <div class="themify_clear_field <?php $meta_value == '' && print( 'hide' ); ?>">
        <a href="#"><?php _e( 'Remove File', 'themify' ); ?></a>
    </div>

    <!-- Field storing URL -->
    <input
            size="55"
            type="text"
            value="<?php echo esc_attr( $meta_value ); ?>"
            id="<?php echo esc_attr( $sanitized_name ); ?>"
            class="themify_input_field themify_upload_field"
            name="<?php echo esc_attr( $meta_box['name'] ); ?>">

    <div class="themify_upload_buttons">
        <?php themify_uploader( $sanitized_name, $featimg_uploader_args) ?>
    </div>

    <?php if ( isset( $meta_box['description'] ) ) : ?>
        <span class="themify_field_description">
            <?php echo wp_kses_post( $meta_box['description'] ); ?>
        </span>
    <?php endif; // meta_box description

    if( ! empty( $meta_box['after'] ) ) echo $meta_box['after'];
}

function themify_meta_field_audio( $args ) {
    $meta_box = $args['meta_box'];
    $sanitized_name = sanitize_html_class( $meta_box['name'] );
    extract( $args, EXTR_OVERWRITE );

    /** Parameters for the uploader @var Array */
    $featimg_uploader_args = array(
        'tomedia'   => true,
        'topost'    => $post_id,
        'medialib'  => true,
        'fields'    => $sanitized_name,
        'formats'   => 'mp3,m4a,ogg,wav,wma',
        'type'      => 'audio',
    );

    $remove_data = array(
        'postid'        => esc_js( $post_id ),
        'customfield'   => esc_js( $meta_box['name'] ),
        'nonce'         => esc_js( $themify_custom_panel_nonce )
    ); ?>

    <div class="themify_clear_field <?php $meta_value == '' && print( 'hide' ); ?>">
        <a href="#"><?php _e( 'Remove Audio', 'themify' ); ?></a>
    </div>

    <!-- Field storing URL -->
    <input
        size="55"
        type="text"
        value="<?php echo esc_attr( $meta_value ); ?>"
        id="<?php echo esc_attr( $sanitized_name ); ?>"
        class="themify_input_field themify_upload_field"
        name="<?php echo esc_attr( $meta_box['name'] ); ?>">

    <div class="themify_upload_buttons">
        <?php themify_uploader( $sanitized_name, $featimg_uploader_args) ?>
    </div>

    <?php if ( isset( $meta_box['description'] ) ) : ?>
        <span class="themify_field_description">
            <?php echo wp_kses_post( $meta_box['description'] ); ?>
        </span>
    <?php endif; // meta_box description

    if( ! empty( $meta_box['after'] ) ) echo $meta_box['after'];
}

function themify_meta_field_postmeta( $args ) {
    extract( $args, EXTR_OVERWRITE );

    foreach($meta_box['meta'] as $meta => $name){
        $metakey = $meta_box['name'].'_'.$meta;
        $meta_class = 'all' != $meta? 'meta-sub meta-'.$meta : 'meta-all';
        echo '
        <label for="' . esc_attr( $metakey ) . '">
            <input type="checkbox" value="no" class="' . esc_attr( $meta_class ) . '" id="' . esc_attr( $metakey ) . '" name="' . esc_attr( $metakey ) . '" /> ' . esc_html( $name ) . '
        </label>';
    }
    ?>
    <br/>
    <input type="hidden" class="widefat" value="<?php echo esc_attr( $meta_value ); ?>" id="<?php echo esc_attr( $meta_box['name'] ); ?>" name="<?php echo esc_attr( $meta_box['name'] ); ?>" />

    <?php if ( isset( $meta_box['description'] ) ) : ?>
        <span class="themify_field_description"><?php echo wp_kses_post( $meta_box['description'] ); ?></span>
    <?php endif; // meta_box description
}

function themify_meta_field_post_id_info( $args ) {
    extract( $args, EXTR_OVERWRITE );
    ?>

    <span class="themify_field_description themify_field_info"><?php echo sprintf( urldecode( $meta_box['description'] ), $post_id ); ?></span>
    <?php
}

/**
 * Generates date picker field for Themify Custom Panel.
 *
 * @param array $args Field settings.
 *
 * @since 1.7.1
 * @return string
 */
function themify_meta_field_date( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);

    if ( isset( $meta_box['meta']['default'] ) && $meta_box['meta']['default'] != '' ) {
        $default = $meta_box['meta']['default'];
    } else {
        $default = '';
    }

    $required = ( isset( $meta_box['meta']['required'] ) && true == $meta_box['meta']['required'] ) ? 'required' : '';

    $pick  = isset( $meta_box['meta']['pick'] ) && '' != $meta_box['meta']['pick'] ? $meta_box['meta']['pick']  : __( 'Pick Date', 'themify' );
    $close = isset( $meta_box['meta']['close'] ) && '' != $meta_box['meta']['close'] ? $meta_box['meta']['close'] : __( 'Done', 'themify' );
    $clear = isset( $meta_box['meta']['clear'] ) && '' != $meta_box['meta']['clear'] ? $meta_box['meta']['clear'] : __( 'Clear', 'themify' );
    $date_format = isset( $meta_box['meta']['date_format'] ) && '' != $meta_box['meta']['date_format'] ? $meta_box['meta']['date_format'] : 'yy-mm-dd';
    $time_format = isset( $meta_box['meta']['time_format'] ) && '' != $meta_box['meta']['time_format'] ? $meta_box['meta']['time_format'] : 'hh:mm tt';
    $timeseparator = isset( $meta_box['meta']['timeseparator'] ) && '' != $meta_box['meta']['timeseparator'] ? $meta_box['meta']['timeseparator'] : ' @ ';

    $html = sprintf( '
        <div class="disableDateField"></div>
        <input %s type="text" id="%s" name="%s" value="%s" data-clear="%s" data-label="%s"
         data-close="%s"
         data-dateformat="%s" data-timeformat="%s" data-timeseparator="%s" class="themify_input_field medium themifyDatePicker" data-first-day="%s" />
        <input type="button" id="%s" data-picker="%s" value="%s" class="button themifyClearDate themifyOpacityTransition %s" >',
    $required, esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), esc_attr( $meta_value? $meta_value : $default ), 'clear-'.esc_attr( $meta_box['name'] ), esc_attr( $pick ), esc_attr( $close ), esc_attr( $date_format ), esc_attr( $time_format ), esc_attr( $timeseparator ), get_option( 'start_of_week', '0' ),
    'clear-'.esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), esc_attr( $clear ), $meta_value? 'themifyFadeIn' : '' );

    if(isset($meta_box['label']) && '' != $meta_box['label'])
        $html = sprintf('<label for="%s">%s %s</label>', esc_attr( $meta_box['name'] ), $html, esc_attr( $meta_box['label'] ));

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if ( isset( $meta_box['before'] ) ) $html = $meta_box['before'] . $html;
    if ( isset( $meta_box['after'] ) ) $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates color picker
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_color( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);
    $format = isset( $meta_box['format'] ) ? $meta_box['format'] : 'hex';
    $default = isset( $meta_box['meta']['default'] ) ? $meta_box['meta']['default'] : '';

    $html = sprintf( '
    <input type="text" id="%s" name="%s" value="%s" class="themify_input_field colorSelectInput" data-format="%s" />
    <input type="button" class="button clearColor" value="' . __('&times;', 'themify') . '">',
        esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), esc_attr( $meta_value? $meta_value : $default ), esc_attr( $format ) );

    if(isset($meta_box['label']) && '' != $meta_box['label'])
        $html = sprintf('<label for="%s">%s %s</label>', esc_attr( $meta_box['name'] ), $html, esc_attr( $meta_box['label'] ));

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if ( isset( $meta_box['before'] ) ) $html = $meta_box['before'] . $html;
    if ( isset( $meta_box['after'] ) ) $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates layout field
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_layout( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract( $args, EXTR_OVERWRITE );
    $ops_html = '';

    foreach ( $meta_box['meta'] as $options ) {
        if ( ( '' == $meta_value || !$meta_value || !isset($meta_value)) && ( isset( $options['selected'] ) && $options['selected'] ) ) {
            $meta_value = $options['value'];
        }
        $class = $meta_value == $options['value']?'selected':'';

        if(isset($meta_box['show_title'])){
            $title = isset($options['title'])? $options['title']: ucwords(str_replace('-', ' ', $options['value']));
        } else {
            $title = '';
        }
                $w= isset($option['w'])?$option['w']:'46';
                $h= isset($option['w'])?$option['w']:'35';
        // Check image src whether absolute url or relative url
        $img_src = ( '' != parse_url( $options['img'], PHP_URL_SCHEME) ) ? $options['img'] : get_template_directory_uri() . '/' . $options['img'];

        $ops_html .= sprintf('<a href="#" class="preview-icon %s"><img src="%s" alt="%s" width="'.$w.'" height="'.$h.'" loading="lazy" decoding="async"/><span class="tm-option-title">%s</span></a>',
            $class, 
            esc_url( $img_src ), 
            esc_attr( $options['value'] ),
            $title
        );
    }

    $html = sprintf('%s<input type="hidden" name="%s" value="%s" class="val" />',
        $ops_html, esc_attr( $meta_box['name'] ), esc_attr( $meta_value ));

    if(isset($meta_box['label']) && '' != $meta_box['label'])
        $html = sprintf('<label for="%s">%s %s</label>', esc_attr( $meta_box['name'] ), $html, esc_attr( $meta_box['label'] ));

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if( isset( $meta_box['before'] ) ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates select field as a button
 *
 * @since 1.3.2
 *
 * @param array $args Field settings
 *
 * @return string
 */
function themify_meta_field_dropdownbutton( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    $name = '';
    extract($args, EXTR_OVERWRITE);

    if(isset($meta_box['main']) && $meta_box['main']) {
        $metakey = $meta_box['name'];
        $meta_class = 'ddbtn-all';
    } else {
        $metakey = $meta_box['name'];
        $meta_class = 'ddbtn-sub';
    }

    $additional_classes = isset( $meta_box['class'] ) ? $meta_box['class'] : '';

    $toggle_class = '';
    $ext_attr = '';
    $toggle_enable = false;
    if( isset($meta_box['toggle']) ){
        $toggle_class .= 'themify-toggle ';
        $toggle_class .= (is_array($meta_box['toggle'])) ? implode(' ', $meta_box['toggle']) : $meta_box['toggle'];
    }
    if( isset($meta_box['default_toggle']) && $meta_box['default_toggle'] == 'hidden' ){
        $ext_attr = 'style="display:none;"';
    }
    if( isset($meta_box['enable_toggle']) && $meta_box['enable_toggle'] == true ) {
        $toggle_class .= ' enable_toggle';
        $toggle_enable = true;
    }

    $first = '';
    $others = '';
    $default_icon = '';

    foreach($meta_box['states'] as $state) {
        $state['icon'] = sprintf( urldecode( $state['icon'] ), THEMIFY_METABOX_URI . '/img' );
        if($state['value'] == $meta_value) {
            $first = '
            <div class="first-ddbtn">
                <a href="#" data-val="'.esc_attr( $state['value'] ).'" data-name="'.esc_attr( $state['name'] ).'" title="'.esc_attr( $state['title'] ).'">
                    <img src="'.esc_attr( $state['icon'] ).'" title="'.esc_attr( $state['title'] ).'" />
                    <span class="ddbtn-name">'.esc_attr( $meta_box['title'] ).'</span>
                </a>
            </div>';
            $selected = 'selected';
        } else {
            $selected = '';
        }
        $others .= '
            <div class="ddbtn">
                <a href="#" data-sel="'.$selected.'" data-val="'.esc_attr( $state['value'] ).'" data-name="'.esc_attr( $state['name'] ).'" title="'.esc_attr( $state['title'] ).'">
                    <img src="'.esc_attr( $state['icon'] ).'" title="'.esc_attr( $state['title'] ).'" />
                    <span class="ddbtn-label">'.esc_attr( $state['name'] ).'</span>
                </a>
            </div>';
        if(isset($state['default']) && $state['default']){
            $default_icon = $state['icon'];
        }
    }

    $html = sprintf('
        <div class="%s %s %s"><div class="dropdownbutton-group multi-ddbtn">
            <div id="%s" class="dropdownbutton-list multi-%s" data-name="%s" data-def-icon="%s">
            %s<div class="dropdownbutton">%s</div>
            </div>
            <input type="hidden" value="%s" class="widefat %s" id="%s" name="%s" />
        </div></div>',
        $additional_classes, esc_attr( $toggle_class ), esc_attr( $ext_attr ),
        esc_attr( $metakey ), esc_attr( $meta_class ), esc_attr( $name ), esc_attr( $default_icon ), // group
        $first, $others, // dropdown
        esc_attr( $meta_value ), esc_attr( $meta_class ), esc_attr( $metakey ), esc_attr( $metakey ) // hidden field
    );

    $html = themify_meta_field_get_label($html, $meta_box);

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if( isset( $meta_box['before'] ) && $meta_box['before'] ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) && $meta_box['after'] )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates select field
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_dropdown( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);

    $ops_html = '';

    /* dynamic data source, call a function to populate the field */
    if( is_callable( $meta_box['meta'] ) ) {
        $meta_box['meta'] = call_user_func( $meta_box['meta'] );
    }

    foreach($meta_box['meta'] as $option){
        $ops_html .= sprintf('<option value="%s" %s>%s</option>',
            esc_attr( $option['value'] ),
            isset( $meta_value ) && '' != $meta_value? selected( $meta_value, esc_attr( $option['value'] ), false )
                : selected( isset( $option['selected'] )? $option['selected'] : '', true, false ),
            esc_html( $option['name'] )
        );
    }

    $html = sprintf('<select id="%s" name="%s">%s</select>',
        esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), $ops_html);

    $html = themify_meta_field_get_label($html, $meta_box);

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if( isset( $meta_box['before'] ) && $meta_box['before'] ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) && $meta_box['after'] )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates radio buttons.
 *
 * @param array $args
 *
 * @return string
 */
function themify_meta_field_radio( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);

    $html = '';
    foreach ( $meta_box['meta'] as $k => $option ) {
        $radio_selected = ( isset( $option['selected'] ) && $option['selected'] && '' == $meta_value ) || ( isset( $meta_box['default'] ) && $option['value'] == $meta_box['default'] && '' == $meta_value ) ? 'checked="checked"' : checked( $meta_value, esc_attr( $option['value'] ), false );
        $disabled = isset( $option['disabled'] ) && $option['disabled'] == true ? 'disabled="disabled"' : '';

        $rid = $meta_box['name'] . '-' . esc_attr( $option['value'] );
        $html .= sprintf( '<input type="radio" name="%s" id="%s" value="%s" %s %s /><label for="%s" class="selectit">%s</label>',
            // radio
            esc_attr( $meta_box['name'] ),
            esc_attr( $rid ),
            esc_attr( $option['value'] ),
            $radio_selected,
            $disabled,
            // label
            esc_attr( $rid ),
            esc_html( $option['name'] )
        );
    }
    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if( isset( $meta_box['before'] ) ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates separator
 *
 * @param array $args Field settings
 * @param bool  $call_before_after Whether to output common wrapping markup before and after the field
 * @param bool  $echo Whether to echo or return the field
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_separator( $args ) {
    $meta_box = $args['meta_box'];
    extract($args, EXTR_OVERWRITE);
    $toggle_class = isset( $args['toggle_class'] ) ? $args['toggle_class'] : '';
    $ext_attr = isset( $args['ext_attr'] ) ? $args['ext_attr'] : '';

    $html = isset($meta_box['meta']['html']) && '' != $meta_box['meta']['html']? $meta_box['meta']['html'] : '<hr class="meta_fields_separator" />';

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    $out = '<div class="themify_field_row tf_clearfix ' . esc_attr( $toggle_class ) . '" ' . esc_attr( $ext_attr );
    if ( isset( $args['data_hide'] ) && ! empty( $args['data_hide'] ) ) {
        $out .= ' data-hide="' . esc_attr( $args['data_hide'] ) . '"';
    }
    $out .= '>' . $html . '</div>';

    echo $out;
}

/**
 * Generates checkbox field
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_checkbox( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);

    $checked = $meta_value || ( isset( $meta_box['default'] ) && 'checked' === $meta_box['default'] && 'auto-draft' === get_post_status() ) ? 'checked="checked"' : '';

    $html = sprintf('<input type="checkbox" id="%s" name="%s" %s class="%s" data-val="%s" />',
        esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), $checked, esc_attr( $meta_box['name'] ).'-toggle-control', esc_attr( $meta_box['name'] ));

    if ( isset( $meta_box['label'] ) && '' != $meta_box['label'] ) {
        $html = sprintf( '<label for="%s">%s %s</label>', esc_attr( $meta_box['name'] ), $html, esc_attr( $meta_box['label'] ) );
    }

    if ( isset( $meta_box['description'] ) ) {
        $html .= themify_meta_field_get_description( $meta_box['description'] );
    }

    if( isset( $meta_box['before'] ) && $meta_box['before'] ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) && $meta_box['after'] )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates text field
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_textbox( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);
    if( isset( $meta_box['default'] ) && empty( $meta_value ) && ! ( $meta_value === 0 || $meta_value === '0' ) ) {
        $meta_value = $meta_box['default'];
    }

    if ( isset( $meta_box['meta']['size'] ) && '' != $meta_box['meta']['size'] ) {
        $class = $meta_box['meta']['size'];
    } else {
        $class = '';
    }

    $html = sprintf('<input type="text" id="%s" name="%s" value="%s" size="55" class="themify_input_field %s" />',
        esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), esc_attr( $meta_value ), $class);

    if ( isset( $meta_box['label'] ) && '' != $meta_box['label'] ) {
        $html = themify_meta_field_get_label($html, $meta_box);
    }

    if ( isset( $meta_box['description'] ) ) {
        $html .= themify_meta_field_get_description( $meta_box['description'] );
    }

    if( isset( $meta_box['before'] ) && $meta_box['before'] ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) && $meta_box['after'] )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Generates textarea field
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_textarea( $args ) {
    extract( $args, EXTR_OVERWRITE );
    $meta_box = wp_parse_args( $meta_box, array(
        'size' => 55,
        'rows' => 4,
        'class' => '',
        'attr' => '',
    ) );
    $meta_value = $args['meta_value'];

    $html = sprintf( '<textarea id="%s" name="%s" size="%s" rows="%s" class="themify_input_field %s" %s>%s</textarea>',
        esc_attr( $meta_box['name'] ), esc_attr( $meta_box['name'] ), $meta_box['size'], $meta_box['rows'], $meta_box['class'], $meta_box['attr'], esc_textarea( $meta_value ) );

    $html = themify_meta_field_get_label($html, $meta_box);

    if ( isset( $meta_box['description'] ) ) {
        $html .= themify_meta_field_get_description( $meta_box['description'] );
    }

    if( isset( $meta_box['before'] ) && $meta_box['before'] ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) && $meta_box['after'] )  $html .= $meta_box['after'];

    echo $html;
}

function themify_meta_field_video( $args ) {
    global $post;

    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract($args, EXTR_OVERWRITE);

    ob_start();

    /** Parameters for the uploader @var Array */
    $featimg_uploader_args = array(
        'tomedia'  => true,
        'topost'   => $post_id,
        'medialib' => true,
        'fields'   => $meta_box['name'],
        'formats'  => 'mp4,m4v,webm,ogv,wmv,flv',
        'type'     => 'video',
    );
    ?>

    <div class="themify_clear_field <?php if( $meta_value == '' ) echo 'hide' ?>">
        <a href="#"><?php _e('Remove Video', 'themify'); ?></a>
    </div>

    <!-- Field storing URL -->
    <input type="text" id="<?php echo esc_attr( $meta_box['name'] ); ?>" name="<?php echo $meta_box['name']; ?>" value="<?php echo esc_attr( $meta_value ); ?>" size="55" class="themify_input_field themify_upload_field" />

    <div class="themify_upload_buttons">
        <?php themify_uploader($meta_box['name'], $featimg_uploader_args) ?>
    </div>
    <?php

    $html = ob_get_contents();
    ob_end_clean();

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if( isset( $meta_box['before'] ) && $meta_box['before'] ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) && $meta_box['after'] )  $html .= $meta_box['after'];

    $html = $html . '<!-- Themify Video END -->';
    echo $html;
}

/**
 * Returns label before or after field
 * @param string $html field markup
 * @param array $meta_box field definition in key => value format
 * @param bool $echo Whether to echo or return the field
 * @return string field markup with label
 * @since 1.3.2
 */
function themify_meta_field_get_label( $html, $meta_box, $echo = false ) {
    $label_for = ( isset( $meta_box['name'] ) && '' != $meta_box['name'] ) ? esc_attr( $meta_box['name'] ) : '';
    if ( isset( $meta_box['label'] ) && '' != $meta_box['label'] ) {
        if ( isset( $meta_box['label_before'] ) && $meta_box['label_before'] ) {
            $html = sprintf( '<label for="%s">%s %s</label>', $label_for, wp_kses_post( $meta_box['label'] ), $html );
        } else {
            $html = sprintf( '<label for="%s">%s %s</label>', $label_for, $html, wp_kses_post( $meta_box['label'] ) );
        }
    }
    if ( $echo ) echo $html;
    return $html;
}

/**
 * Renders description for meta fields.
 *
 * @uses wp_kses_post()
 *
 * @param string $desc
 *
 * @return string
 */
function themify_meta_field_get_description( $desc = '' ) {
    return ( isset( $desc ) && '' != $desc ) ? '<span class="themify_field_description">' . wp_kses_post( $desc ) . '</span>' : '';
}

function themify_ajax_create_page_pagination() {
    if ( ! current_user_can( 'edit_posts' ) ) {
        die;
    }

    $current_page = isset( $_POST['current_page'] ) ? (int) $_POST['current_page'] : 1;
    $num_of_pages = isset( $_POST['num_of_pages'] ) ? (int) $_POST['num_of_pages'] : 0;
    echo themify_create_page_pagination($current_page, $num_of_pages);
    die;
}

/**
 * Render pagination for specific page.
 *
 * @param Integer $current_page The current page that needs to be rendered.
 * @param Integer $num_of_pages The number of all pages.
 *
 * @return String The HTML with pagination.
 */
function themify_create_page_pagination( $current_page, $num_of_pages ) {
    $links_in_the_middle = 4;
    $links_in_the_middle_min_1 = $links_in_the_middle - 1;
    $first_link_in_the_middle   = $current_page - floor( $links_in_the_middle_min_1 / 2 );
    $last_link_in_the_middle    = $current_page + ceil( $links_in_the_middle_min_1 / 2 );
    if ( $first_link_in_the_middle <= 0 ) {
        $first_link_in_the_middle = 1;
    }
    if ( ( $last_link_in_the_middle - $first_link_in_the_middle ) != $links_in_the_middle_min_1 ) {
        $last_link_in_the_middle = $first_link_in_the_middle + $links_in_the_middle_min_1;
    }
    if ( $last_link_in_the_middle > $num_of_pages ) {
        $first_link_in_the_middle = $num_of_pages - $links_in_the_middle_min_1;
        $last_link_in_the_middle  = (int) $num_of_pages;
    }
    if ( $first_link_in_the_middle <= 0 ) {
        $first_link_in_the_middle = 1;
    }
    $pagination = '';
    if ( $current_page != 1 ) {
        $pagination .= '<a href="/page/' . ( $current_page - 1 ) . '" class="prev page-numbers"><span class="page-numbers-icon"></span></a>';
    }
    if ( $first_link_in_the_middle >= 3 && $links_in_the_middle < $num_of_pages ) {
        $pagination .= '<a href="/page/" class="page-numbers">1</a><span class="page-numbers extend">...</span>';
    }
    for ( $i = $first_link_in_the_middle; $i <= $last_link_in_the_middle; $i ++ ) {
        if ( $i == $current_page ) {
            $pagination .= '<span class="page-numbers current">' . $i . '</span>';
        } else {
            $pagination .= '<a href="/page/' . $i . '" class="page-numbers">' . $i . '</a>';
        }
    }
    if ( $last_link_in_the_middle < $num_of_pages ) {
        if ( $last_link_in_the_middle != ( $num_of_pages - 1 ) ) {
            $pagination .= '<span class="page-numbers extend">...</span>';
        }
        $pagination .= '<a href="/page/' . $num_of_pages . '" class="page-numbers">' . $num_of_pages . '</a>';
    }
    if ( $current_page != $last_link_in_the_middle ) {
        $pagination .= '<a href="/page/' . ( $current_page + $i ) . '" class="next page-numbers"><span class="page-numbers-icon"></span></a>';
    }

    return $pagination;
}

function themify_ajax_create_inner_page() {
    if ( ! current_user_can( 'edit_posts' ) ) {
        die;
    }

    $selected = array();
    if ( isset( $_POST['post_id'] ) ) {
        $post_id = (int) $_POST['post_id'];
        $selected = get_post_meta( $post_id, 'popup_show', TRUE );
    }
    $type= isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : 'pages';
    echo themify_create_inner_page($type, $selected);
    die;
}

/**
 * Renders pages, posts types and categories items based on current page.
 *
 * @param string $type The type of items to render.
 * @param array $selected The array of all selected options.
 *
 * @return string The HTML to render items as HTML.
 */
function themify_create_inner_page( $type, $selected ) {
    $posts_per_page = 26;
    $output = '';
    switch ($type) {
        case 'page':
            $key = 'page';
            $posts = get_posts( array( 'post_type' => $key, 'posts_per_page' => -1, 'post_status' => 'publish', 'order' => 'ASC', 'orderby' => 'title',  'no_found_rows' => true,'ignore_sticky_posts'=>true) );
            if( ! empty( $posts ) ) {
                $i = 1;
                $page_id = 1;
                $num_of_single_pages = count($posts);
                $num_of_pages = (int) ceil( $num_of_single_pages / $posts_per_page );
                $output .= '<div class="themify-assignment-items-inner" data-items="' . $num_of_single_pages . '" data-pages="' . $num_of_pages . '">';
                $output .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . '">';
                foreach ( $posts as $post ) :
                    if ( $post->post_parent > 0 ) {
                        $post->post_name = str_replace( home_url(), '', get_permalink( $post->ID ) );
                    }
                    $checked = isset( $selected['post_type'][ $key ][ $post->post_name ] ) ? checked( $selected['post_type'][ $key ][ $post->post_name ], 'on', false ) : '';
                    /* note: slugs are more reliable than IDs, they stay unique after export/import */
                    $output .= '<label><input type="checkbox" data-name="popup_show[post_type][' . $key . '][' . $post->post_name . ']"' . $checked . ' />' . $post->post_title . '</label>';
                    if ( $i === ($page_id * $posts_per_page) ) {
                        $output .= '</div>';
                        $page_id++;
                        $output .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . ' is-hidden">';
                    }
                    $i++;
                endforeach;
                $output .= '</div>';
                if ( $num_of_pages > 1 ) {
                    $output .= '<div class="themify-assignment-pagination">';
                    $output .= themify_create_page_pagination( 1, $num_of_pages );
                    $output .= '</div>';
                }
                $output .= '</div>';
            }
            break;

        case 'category_single':
            $key = 'category_single';
            $terms = get_terms( array('taxonomy'=>'category', 'hide_empty' => true ) );
            if ( ! empty( $terms ) ) {
                $i                   = 1;
                $page_id             = 1;
                $num_of_single_pages = count( $terms );
                $num_of_pages        = (int) ceil( $num_of_single_pages / $posts_per_page );
                $output              .= '<div class="themify-assignment-items-inner" data-items="' . $num_of_single_pages . '" data-pages="' . $num_of_pages . '">';
                $output              .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . '">';
                foreach ( $terms as $term ) :
                    $checked = isset( $selected['tax'][ $key ][ $term->slug ] ) ? checked( $selected['tax'][ $key ][ $term->slug ], 'on', false ) : '';
                    $output  .= '<label><input type="checkbox" data-name="popup_show[tax][' . $key . '][' . $term->slug . ']" ' . $checked . ' />' . $term->name . '</label>';
                    if ( $i === ( $page_id * $posts_per_page ) ) {
                        $output .= '</div>';
                        $page_id ++;
                        $output .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . ' is-hidden">';
                    }
                    $i++;
                endforeach;
                $output .= '</div>';
                if ( $num_of_pages > 1 ) {
                    $output .= '<div class="themify-assignment-pagination">';
                    $output .= themify_create_page_pagination( 1, $num_of_pages );
                    $output .= '</div>';
                }
                $output .= '</div>';
            }
            break;

        case 'category':
            $key = 'category';
            $terms = get_terms( array('taxonomy'=>'category',  'hide_empty' => true ) );
            if ( ! empty( $terms ) ) {
                $i                   = 1;
                $page_id             = 1;
                $num_of_single_pages = count( $terms );
                $num_of_pages        = (int) ceil( $num_of_single_pages / $posts_per_page );
                $output              .= '<div class="themify-assignment-items-inner" data-items="' . $num_of_single_pages . '" data-pages="' . $num_of_pages . '">';
                $output              .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . '">';
                foreach ( $terms as $term ) :
                    $checked = isset( $selected['tax'][ $key ][ $term->slug ] ) ? checked( $selected['tax'][ $key ][ $term->slug ], 'on', false ) : '';
                    $output  .= '<label><input type="checkbox" data-name="popup_show[tax][' . $key . '][' . $term->slug . ']" ' . $checked . ' />' . $term->name . '</label>';
                    if ( $i === ( $page_id * $posts_per_page ) ) {
                        $output .= '</div>';
                        $page_id ++;
                        $output .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . ' is-hidden">';
                    }
                    $i++;
                endforeach;
                $output .= '</div>';
                if ( $num_of_pages > 1 ) {
                    $output .= '<div class="themify-assignment-pagination">';
                    $output .= themify_create_page_pagination( 1, $num_of_pages );
                    $output .= '</div>';
                }
                $output .= '</div>';
            }
            break;

        default :
            $post_types = get_post_types( array( 'public' => true ) );
            unset( $post_types['page'] );
            $post_types = array_map( 'get_post_type_object', $post_types );
            $post_id = 1;
            foreach ( $post_types as $key => $post_type ) {
                $output .= '<div id="popup_show-assignment-tab-' . $key . '" class="themify-assignment-inner-tab '. ($post_id > 1 ? 'is-hidden' : '') .'">';
                $posts = get_posts( array( 'post_type' => $key, 'posts_per_page' => -1, 'post_status' => 'publish', 'order' => 'ASC', 'orderby' => 'title',  'no_found_rows' => true,'ignore_sticky_posts'=>true ) );
                if ( ! empty( $posts ) ) {
                    $i                   = 1;
                    $page_id             = 1;
                    $num_of_single_pages = count( $posts );
                    $num_of_pages        = (int) ceil( $num_of_single_pages / $posts_per_page );
                    $output              .= '<div class="themify-assignment-items-inner" data-items="' . $num_of_single_pages . '" data-pages="' . $num_of_pages . '">';
                    $output              .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . '">';
                    foreach ( $posts as $post ) {
                        $checked = isset( $selected['post_type'][ $key ][ $post->post_name ] ) ? checked( $selected['post_type'][ $key ][ $post->post_name ], 'on', false ) : '';
                        /* note: slugs are more reliable than IDs, they stay unique after export/import */
                        $output .= '<label><input type="checkbox" data-name="' . esc_attr( 'popup_show[post_type][' . $key . '][' . $post->post_name . ']' ) . '" ' . $checked . ' />' . esc_html( $post->post_title ) . '</label>';
                        if ( $i === ( $page_id * $posts_per_page ) ) {
                            $output .= '</div>';
                            $page_id ++;
                            $output .= '<div class="themify-assignment-items-page themify-assignment-items-page-' . $page_id . ' is-hidden">';
                        }
                        $i++;
                    }
                    $output .= '</div>';
                    if ( $num_of_pages > 1 ) {
                        $output .= '<div class="themify-assignment-pagination">';
                        $output .= themify_create_page_pagination( 1, $num_of_pages );
                        $output .= '</div>';
                    }
                }
                $output .= '</div></div></div>';
                $post_id++;
            }
            $output .= '</div>';
            break;
    }
    wp_reset_postdata();

    return $output;
}

function themify_meta_field_assignments( $args ) {
    extract( $args );
    $field = $meta_box;
    $pre = $field['name'];
    $selected = $meta_value;
    if( '' == $selected )
        $selected = array();
    $post_types = apply_filters( 'themify_assignments_post_types', get_post_types( array( 'public' => true ) ) );
    unset( $post_types['page'] );
    unset( $post_types['attachment'] );
    if( isset( $field['exclude_post_types'] ) ) {
        foreach( $field['exclude_post_types'] as $type ) {
            unset( $post_types[$type] );
        }
    }
    $post_types = array_map( 'get_post_type_object', $post_types );

    $taxonomies = apply_filters( 'themify_assignments_taxonomies', get_taxonomies( array( 'public' => true ) ) );
    unset( $taxonomies['category'] );
    if( isset( $field['exclude_taxonomies'] ) ) {
        foreach( $field['exclude_taxonomies'] as $tax ) {
            unset( $taxonomies[$tax] );
        }
    }
    $taxonomies = array_map( 'get_taxonomy', $taxonomies );

    $output = '<div id="themify_assignments_'. $pre .'" class="themify-assignments"><ul class="tf_clearfix">';

    /* build the tab links */
    $output .= '<li><a href="#' . $pre . '-assignment-tab-general">' . __( 'General', 'themify' ) . '</a></li>';
    $output .= '<li><a href="#' . $pre . '-assignment-tab-pages" class="themify-popup-visibility-tab" data-type="page">' . __( 'Pages', 'themify' ) . '</a></li>';
    $output .= '<li><a href="#' . $pre . '-assignment-tab-categories-singles" class="themify-popup-visibility-tab" data-type="category_single">' . __( 'In Category', 'themify' ) . '</a></li>';
    $output .= '<li><a href="#' . $pre . '-assignment-tab-categories" class="themify-popup-visibility-tab" data-type="category">' . __( 'Category Archives', 'themify' ) . '</a></li>';
    $output .= '<li><a href="#' . $pre . '-assignment-tab-post-types" class="themify-popup-visibility-tab" data-type="post">' . __( 'Post Types', 'themify' ) . '</a></li>';
    $output .= '<li><a href="#' . $pre . '-assignment-tab-taxonomies">' . __( 'Taxonomies', 'themify' ) . '</a></li>';
    $output .= '<li><a href="#' . $pre . '-assignment-tab-userroles">' . __( 'User Roles', 'themify' ) . '</a></li>';
    $output .= '</ul>';

    /* build the tab items */
    $output .= '<div id="' . $pre . '-assignment-tab-general" class="themify-assignment-options tf_clearfix">';
    $checked = isset($selected['general']['home']) ? checked($selected['general']['home'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][home]" ' . $checked . ' />' . __( 'Home page', 'themify' ) . '</label>';
    $checked = isset($selected['general']['page']) ? checked($selected['general']['page'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][page]" ' . $checked . ' />' . __( 'Page views', 'themify' ) . '</label>';
    $checked = isset($selected['general']['single']) ? checked($selected['general']['single'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][single]" ' . $checked . ' />' . __( 'Single post views', 'themify' ) . '</label>';
    $checked = isset($selected['general']['search']) ? checked($selected['general']['search'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][search]" ' . $checked . ' />' . __( 'Search pages', 'themify' ) . '</label>';
    $checked = isset($selected['general']['category']) ? checked($selected['general']['category'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][category]" ' . $checked . ' />' . __( 'Category archive', 'themify' ) . '</label>';
    $checked = isset($selected['general']['tag']) ? checked($selected['general']['tag'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][tag]" ' . $checked . ' />' . __( 'Tag archive', 'themify' ) . '</label>';
    $checked = isset($selected['general']['author']) ? checked($selected['general']['author'], 'on', false) : '';
    $output .= '<label><input type="checkbox" data-name="' . $pre . '[general][author]" ' . $checked . ' />' . __( 'Author pages', 'themify' ) . '</label>';

    /* General views for CPT */
    foreach ( get_post_types( array( 'public' => true, 'exclude_from_search' => false, '_builtin' => false ) ) as $key => $post_type ) {
        $post_type = get_post_type_object( $key );
        $checked = isset( $selected['general'][$key] ) ? checked( $selected['general'][$key], 'on', false ) : '';
        $output .= '<label><input type="checkbox" data-name="' . esc_attr( $pre . '[general][' . $key . ']' ) . '" ' . $checked . ' />' . sprintf( __( 'Single %s View', 'themify' ), $post_type->labels->singular_name ) . '</label>';
    }

    /* Custom taxonomies archive view */
    foreach ( get_taxonomies( array( 'public' => true, '_builtin' => false ) ) as $key => $tax ) {
        $tax = get_taxonomy( $key );
        $checked = isset( $selected['general'][$key] ) ? checked( $selected['general'][$key], 'on', false ) : '';
        $output .= '<label><input type="checkbox" data-name="' . esc_attr( $pre . '[general][' . $key . ']' ) . '" ' . $checked . ' />' . sprintf( __( '%s Archive View', 'themify' ), $tax->labels->singular_name ) . '</label>';
    }

    $output .= '</div>'; // tab-general
    // Pages tab
    wp_reset_postdata();
    $output .= '<div id="' . $pre . '-assignment-tab-pages" class="themify-assignment-options themify-assignment-type-options tf_clearfix"  data-type="page" data-post-id="' . get_the_ID() . '">';
    $output .= '</div>'; // tab-pages
    // Category Singles tab
    $output .= '<div id="' . $pre . '-assignment-tab-categories-singles" class="themify-assignment-options themify-assignment-type-options tf_clearfix" data-type="category_single">';
    $output .= '</div>';

    // Categories tab
    $output .= '<div id="' . $pre . '-assignment-tab-categories" class="themify-assignment-options themify-assignment-type-options tf_clearfix" data-type="category">';
    $output .= '</div>'; // tab-categories
    // Post types tab
    $output .= '<div id="' . $pre . '-assignment-tab-post-types" class="themify-assignment-options tf_clearfix" data-type="post">';
    $output .= '<div id="' . $pre . '-themify-assignment-post-types-inner-tabs" class="themify-assignment-inner-tabs">';
    $output .= '<ul class="inline-tabs tf_clearfix">';
    foreach ( $post_types as $key => $post_type ) {
        $output .= '<li><a href="#' . $pre . '-assignment-tab-' . $key . '">' . esc_html( $post_type->label ) . '</a></li>';
    }
    $output .= '</ul>';
    $output .= '<div class="themify-assignment-type-options tf_clearfix" data-type="post"></div>';
    $output .= '</div>';
    $output .= '</div>'; // tab-post-types
    // Taxonomies tab
    $output .= '<div id="' . $pre . '-assignment-tab-taxonomies" class="themify-assignment-options tf_clearfix">';
    $output .= '<div id="' . $pre . '-themify-assignment-taxonomies-inner-tabs" class="themify-assignment-inner-tabs">';
    $output .= '<ul class="inline-tabs tf_clearfix">';
    foreach ( $taxonomies as $key => $tax ) {
        $output .= '<li><a href="#' . $pre . '-assignment-tab-' . $key . '">' . esc_html($tax->label) . '</a></li>';
    }
    $output .= '</ul>';
    foreach ( $taxonomies as $key => $tax ) {
        $output .= '<div id="' . $pre . '-assignment-tab-' . $key . '" class="tf_clearfix">';
        $terms = get_terms( array('taxonomy'=>$key,  'hide_empty' => true ) );
        if ( ! empty( $terms ) ) : foreach ( $terms as $term ) :
                $checked = isset( $selected['tax'][$key][$term->slug] ) ? checked( $selected['tax'][$key][$term->slug], 'on', false ) : '';
                $output .= '<label><input type="checkbox" data-name="' . esc_attr( $pre . '[tax][' . $key . '][' . $term->slug . ']' ) . '" ' . $checked . ' />' . esc_html( $term->name ) . '</label>';
            endforeach;
        endif;
        $output .= '</div>';
    }
    $output .= '</div>';
    $output .= '</div>'; // tab-taxonomies
    // User Roles tab
    $output .= '<div id="' . $pre . '-assignment-tab-userroles" class="themify-assignment-options tf_clearfix">';
    foreach ( $GLOBALS['wp_roles']->roles as $key => $role ) {
        $checked = isset( $selected['roles'][$key] ) ? checked( $selected['roles'][$key], 'on', false ) : '';
        $output .= '<label><input type="checkbox" data-name="' . esc_attr( $pre . '[roles][' . $key . ']' ) . '" ' . $checked . ' />' . esc_html( $role['name'] ) . '</label>';
    }
    $output .= '</div>'; // tab-userroles

    $output .= '<div class="values">';
        $output .= themify_array_to_input( $selected, $pre );
    $output .= '</div>';

    $output .= '</div>';

    echo $output;
}


/**
 * Returns a PLUPLOAD instance. If it's a multisite, checks user quota and shows message if it's not enough to continue upload files.
 *
 * @param string $id
 * @param array $params $label = '', $thumbs = false, $filelist = false, $multiple = false, $message = '', $fallback = ''
 *
 * @return string
 */
function themify_get_uploader( $id = '', $args = array() ){

    $defaults = array(
        'label'     => __('Upload', 'themify'),
        'preset'    => false,
        'preview'   => false,
        'tomedia'   => false,
        'topost'    => '',
        'fields'    => '',
        'featured'  => '',
        'message'   => '',
        'fallback'  => '',
        'dragfiles' => false,
        'confirm'   => '',
        'medialib'  => false,
        'formats'   => 'jpg,jpeg,gif,png,ico,zip,txt,svg',
        'type'      => 'image',
        'action'    => 'themify_plupload',
        'button_class' => '',
    );
    // Extract $label, $preset, $thumbs, $filelist, $multiple, $message, $fallback, $confirm
    $args = wp_parse_args($args, $defaults);

    $upload_visible = false;

    if ( is_multisite() && !is_upload_space_available() ) {
        if( '' != $args['message'] ){
            $html = $args['message'];
        } else {
            $html = '<small>' . sprintf( __( 'Sorry, you have filled your %s MB storage quota so uploading has been disabled.', 'themify' ), get_space_allowed() ) . '</small>';
        }
    } else {
        if( '' != $args['fallback'] )
            $html = $args['fallback'];
        else {
            ob_start();
            // $id is the name of form field. File urls will be submitted in $_POST using this key.
            // If $id == "file" then $_POST["file"] will have all the file urls
            ?>
            <!--<input type="hidden" name="<?php echo esc_attr( $id ); ?>" id="<?php echo esc_attr( $id ); ?>" value="" />-->
            <?php if( $args['dragfiles'] ){ ?>
                <div id="<?php echo esc_attr( $id . 'drag-drop-area' ); ?>" class="plupload-drag-drop-area">
            <?php } ?>
                <?php
                $classes = '';
                if($args['preset']) $classes .= 'add-preset ';
                if($args['preview']) $classes .= 'add-preview ';
                if($args['tomedia']) $classes .= 'add-to-media ';

                $datas = array();
                if('' != $args['topost']) $datas[] = 'data-postid="' . esc_attr( $args['topost'] ) . '"';
                if('' != $args['fields']) $datas[] = 'data-fields="' . esc_attr( $args['fields'] ) . '"';
                if('' != $args['confirm']) $datas[] = 'data-confirm="' . esc_attr( $args['confirm'] ) . '"';
                if('' != $args['featured']) $datas[] = 'data-featured="' . esc_attr( $args['featured'] ) . '"';
                if('' != $args['formats']) $datas[] = 'data-formats="' . esc_attr( $args['formats'] ) . '"';
                $datas[] = 'data-action="' . esc_attr( $args['action'] ) . '"';
                ?>
                <div class="plupload-upload-uic hide-if-no-js <?php echo esc_attr( $classes ); ?>" <?php echo implode( ' ', $datas ); ?> id="<?php echo esc_attr( $id ); ?>plupload-upload-ui" data-type="<?php esc_attr_e( $args['type'] ); ?>">

                    <input id="<?php echo esc_attr( $id ); ?>plupload-browse-button" type="button" value="<?php echo esc_attr( $args['label'] ); ?>" class="button plupload-button <?php echo esc_attr( 'plupload-' . $id . ' ' . $args['button_class'] ); ?>" />

                    <span class="ajaxnonceplu" id="ajaxnonceplu<?php echo wp_create_nonce($id . 'themify-plupload'); ?>"></span>

                </div>

            <?php if( $args['dragfiles'] ){ ?>
                    <small><?php _e(' or drag files here.', 'themify'); ?></small>
                </div>
            <?php } else { ?>
                <span id="<?php echo esc_attr( $id . 'drag-drop-area' ); ?>" style="display: none;"></span>
            <?php }
            
            $html = ob_get_contents();
            ob_end_clean();
        }
        $upload_visible = true;
    }

    if( $args['medialib'] ) {
        ob_start();
        ?>
        <?php
            if ( 'audio' == $args['type'] ) {
                $data_uploader_title = __( 'Browse Audio', 'themify' );
                $medialib_btn_text = __('Insert Audio', 'themify');
            } elseif ( 'video' == $args['type'] ) {
                $data_uploader_title = __( 'Browse Video', 'themify' );
                $medialib_btn_text = __('Insert Video', 'themify');
            } elseif ( in_array($args['formats'],array('woff','woff2','eot','ttf','svg')) ) {
                $data_uploader_title = __( 'Browse Font', 'themify' );
                $medialib_btn_text = __('Insert Font', 'themify');
            }else {
                $data_uploader_title = __( 'Browse Image', 'themify' );
                $medialib_btn_text = __('Insert Image', 'themify');
            }
            $medialib_datas = array(
                'action' => 'themify_metabox_media_lib_browse',
                'media_lib_nonce' => wp_create_nonce( 'media_lib_nonce' ),
                'featured' => ($args['featured'] != '') ? 1 : 0,
                'field_name' => $args['fields'],
                'post_id' => $args['topost']
            );
        ?>
        <div class="themify_medialib_wrapper">
            <?php if($upload_visible): echo '&nbsp;<em>' . __( 'or', 'themify' ) . '</em>'; endif; ?>&nbsp;
            <a href="#" class="themify-media-lib-browse" data-submit='<?php echo json_encode( $medialib_datas ); ?>' data-uploader-title="<?php echo esc_attr( $data_uploader_title ) ?>" data-uploader-button-text="<?php echo esc_attr( $medialib_btn_text ); ?>" data-fields="<?php echo esc_attr( $args['fields'] ); ?>" data-type="<?php echo esc_attr( $args['type'] ); ?>"><?php _e( 'Browse Library', 'themify' ) ?></a>
        </div>
        <?php
        $html .= ob_get_contents();
        ob_end_clean();
    }

    return $html;
}

/**
 * Echoes a PLUPLOAD uploader
 *
 * @uses themify_get_uploader
 *
 * @param string $id
 * @param array $args
 *
 */
function themify_uploader($id = '', $args = array()){
    echo themify_get_uploader( $id, $args );
}

function themify_wp_ajax_plupload_image() {
    $imgid = (int) $_POST['imgid'];
    check_ajax_referer($imgid . 'themify-plupload');
    if( ! current_user_can( 'upload_files' ) ) {
        die;
    }

    /** Decide whether to send this image to Media. @var String */
    $add_to_media_library = isset( $_POST['tomedia'] ) ? sanitize_text_field( $_POST['tomedia'] ) : false;
    /** If post ID is set, uploaded image will be attached to it. @var String */
    $postid = isset( $_POST['topost'] )? (int) $_POST['topost'] : '';
 
    /** Handle file upload storing file|url|type. @var Array */
    $file = wp_handle_upload($_FILES[$imgid . 'async-upload'], array('test_form' => true, 'action' => 'themify_plupload'));
    
    // if $file returns error, return it and exit the function
    if ( isset( $file['error'] ) && ! empty( $file['error'] ) ) {
        echo json_encode($file);
        exit;
    }

    //let's see if it's an image, a zip file or something else
    $ext = explode('/', $file['type']);
    
    //Image Upload routines
    if( 'tomedia' == $add_to_media_library ) {
        
        // Insert into Media Library
        // Set up options array to add this file as an attachment
        $attachment = array(
            'post_mime_type' => sanitize_mime_type($file['type']),
            'post_title' => str_replace('-', ' ', sanitize_file_name(pathinfo($file['file'], PATHINFO_FILENAME))),
            'post_status' => 'inherit'
        );
        
        if( $postid ){
            $attach_id = wp_insert_attachment( $attachment, $file['file'], $postid );
        } else {
            $attach_id = wp_insert_attachment( $attachment, $file['file'] );
        }
        $file['id'] = $attach_id;

        // Common attachment procedures
        require_once(ABSPATH . "wp-admin" . '/includes/image.php');
        $attach_data = wp_generate_attachment_metadata( $attach_id, $file['file'] );
        wp_update_attachment_metadata($attach_id, $attach_data);
        
        if( $postid ) {
            
            $full = wp_get_attachment_image_src( $attach_id, 'full' );
            $fields = sanitize_text_field( $_POST['fields'] );
            update_post_meta( $postid, $fields, $full[0] );
            update_post_meta( $postid, '_' . $fields . '_attach_id', $attach_id );
        }

        $thumb = wp_get_attachment_image_src( $attach_id, 'thumbnail' );

        //Return URL for the image field in meta box
        $file['thumb'] = $thumb[0];
    }
    $file['type'] = $ext[1];
    // send the uploaded file url in response
    echo json_encode( $file );
    exit;
}

/**
 * @todo: remove this
 */
function themify_metabox_media_lib_browse() {
    if ( ! wp_verify_nonce( $_POST['media_lib_nonce'], 'media_lib_nonce' ) ) die(-1);
    if( ! current_user_can( 'upload_files' ) ) {
        die;
    }

    $file = array();
    $postid = (int) $_POST['post_id'];
    $attach_id = (int) $_POST['attach_id'];

    $full = wp_get_attachment_image_src( $attach_id, 'full' );
    update_post_meta($postid, sanitize_text_field( $_POST['field_name'] ), $full[0]);
    update_post_meta($postid, '_' . sanitize_text_field( $_POST['field_name'] ) . '_attach_id', $attach_id);

    $thumb = wp_get_attachment_image_src( $attach_id, 'thumbnail' );

    //Return URL for the image field in meta box
    $file['thumb'] = $thumb[0];

    echo json_encode($file);

    exit();
}

function themify_meta_field_gallery_shortcode( $args ) {
    extract( $args );
    wp_enqueue_script( 'gallery-shortcode' );

    if( isset($meta_box['meta']) && '' != $meta_box['meta']['size'] && 'small' == $meta_box['meta']['size'] ) {
        $class = 'small';
    } else {
        $class = '';
    }
    ?>
    <textarea name="<?php echo esc_attr( $meta_box['name'] ); ?>" size="55" rows="4" class="themify_input_field themify-gallery-shortcode-input <?php echo esc_attr( $class ); ?>"><?php echo esc_textarea( $meta_value ); ?></textarea>

    <div class="themify-gallery-shortcode-btn">
        <a href="#" class="themify-gallery-shortcode-btn"><?php _e('&#8618; Insert Gallery', 'themify') ?></a>
    </div>

    <?php if ( isset( $meta_box['description'] ) ) : ?>
        <span class="themify_field_description"><?php echo wp_kses_post( $meta_box['description'] ); ?></span>
    <?php endif; // meta_box description ?>
    <?php
}

function themify_meta_field_multi( $args, $call_before_after = true, $echo = true ) {
    global $post;
    extract( $args, EXTR_OVERWRITE );

    foreach ($meta_box['meta']['fields'] as $field) {
        if ( is_callable( 'themify_meta_field_'.$field['type'] ) ) {
            // @todo
            if( isset( $field['display_callback'] ) && is_callable( $field['display_callback'] ) ) {
                $show = (bool) call_user_func( $field['display_callback'], $field );
                if( ! $show ) { // if display_callback returns "false",
                    continue;  // do not output the field
                }
            }
            $call_args = array(
                'meta_box' => $field,
                'meta_value' => get_post_meta( $post_id, $field['name'], true ),
                'call_before_after' => false,
                'post_id' => $post_id,
                'themify_custom_panel_nonce' => $themify_custom_panel_nonce,
            );

            // Do nested toggle for multi fields
            if ( isset( $field['enable_toggle'] ) ) {
                echo '<div class="enable_toggle ' . $field['enable_toggle'] . '">';
            } elseif ( isset( $field['toggle'] ) ) {
                $field_toggle = is_array( $field['toggle'] ) ? implode( ' ', $field['toggle'] ) : $field['toggle'];
                echo '<div class="themify-toggle ' . $field_toggle . '">';
            }

            // Render the field
            call_user_func('themify_meta_field_'.$field['type'], $call_args);

            // End nested toggle for multi fields
            if ( isset( $field['enable_toggle'] ) ) {
                echo '</div>';
            } elseif ( isset( $field['toggle'] ) ) {
                echo '</div>';
            }
            if ( ! ( $field === end( $meta_box['meta']['fields'] ) ) ) {
                echo isset( $meta_box['meta']['separator'] ) ? $meta_box['meta']['separator'] : '';
            }
        }
    }
    if ( isset( $meta_box['meta']['description'] ) && '' != $meta_box['meta']['description'] ) {
        echo '<span class="themify_field_description">' . $meta_box['meta']['description'] . '</span>';
    }
}

if( ! function_exists( 'themify_meta_field_query_category' ) ) :
/**
 * query_category field type, display an option to select categories for Query Posts feature
 *
 * @since 2.8.8
 */
function themify_meta_field_query_category( $args ) {
    extract( $args );

    $terms_tax = isset($meta_box['meta']['taxonomy'])? $meta_box['meta']['taxonomy']: 'category';

    $terms_options = '';
    $terms_by_tax = get_terms($terms_tax);
    if( ! empty( $terms_by_tax ) && ! is_wp_error( $terms_by_tax ) ) {
        $terms_list = array();
        $terms_list['0'] = array(
            'title' => __( 'All Categories', 'themify' ),
            'slug'  => '0'
        );
        foreach ($terms_by_tax as $term) {
            $terms_list[$term->term_id] = array(
                'title' => $term->name,
                'slug'  => $term->slug
            );
        }
        foreach ($terms_list as $term_id => $term) {
            $term_selected = '';
            if(!is_numeric($meta_value)) {
                if($meta_value == $term['slug']) $term_selected = 'selected="selected"';
            } else {
                if($meta_value == $term_id) $term_selected = 'selected="selected"';
            }
            $terms_options .= sprintf(
                '<option value="%s" data-termid="%s" %s>%s</option>',
                $term['slug'],
                $term_id,
                $term_selected,
                $term['title']
            );
        }
        ?>
        <select id="<?php echo esc_attr( $meta_box['name'] ); ?>" class="query_category_single">
            <option></option>
            <?php echo !empty( $terms_options ) ? $terms_options : ''; ?>
        </select>
        <?php _e('or', 'themify'); ?>
    <?php } ?> 
    <input type="text" class="query_category" value="<?php echo esc_attr( $meta_value ); ?>">

    <input type="hidden" value="<?php echo esc_attr( $meta_value ); ?>" name="<?php echo esc_attr( $meta_box['name'] ); ?>" class="val">
    <?php if ( isset( $meta_box['description'] ) ) : ?>
        <span class="themify_field_description"><?php echo wp_kses_post( $meta_box['description'] ); ?></span>
    <?php endif; // meta_box description
}
endif;

function themify_meta_field_repeater_template( $meta_box, $data, $id ) {
    echo '<div class="themify-repeater-row" data-id="'. $id .'">',
        '<div class="themify-repeater-remove-row"><a href="#"></a></div>';
    foreach ( $meta_box['fields'] as $field ) {
        if ( is_callable( 'themify_meta_field_'.$field['type'] ) ) {
            echo '<div class="themify_field_row tf_clearfix">';
            ! empty( $field['title'] ) && printf( '<div class="themify_field_title">%s</div>', $field['title'] );
            $field_id = $field['name'];
            $field['name'] = $meta_box['name'] . '[' . $id . '][' . $field['name'] . ']';

            $call_args = array(
                'meta_box' => $field,
                'meta_value' => isset( $data[$field_id] ) ? $data[$field_id] : '',
                'call_before_after' => false,
                'post_id' => 0,
                'themify_custom_panel_nonce' => 0,
            );

            // Do nested toggle for multi fields
            if ( isset( $field['enable_toggle'] ) ) {
                echo '<div class="enable_toggle ' . $field['enable_toggle'] . '">';
            } elseif ( isset( $field['toggle'] ) ) {
                $field_toggle = is_array( $field['toggle'] ) ? implode( ' ', $field['toggle'] ) : $field['toggle'];
                echo '<div class="themify-toggle ' . $field_toggle . '">';
            }

            printf( '<div class="themify_field themify_field-%s">', $field['type'] );
                // Render the field
                call_user_func('themify_meta_field_'.$field['type'], $call_args);
            echo '</div>';

            // End nested toggle for multi fields
            if ( isset( $field['enable_toggle'] ) || isset( $field['toggle'] )) {
                echo '</div>';
            }
            if ( ! ( $field === end( $meta_box['fields'] ) ) ) {
                echo isset( $meta_box['meta']['separator'] ) ? $meta_box['meta']['separator'] : '';
            }

            echo '</div>';
        }
    }
    echo '</div>';
}

function themify_meta_field_repeater( $args, $call_before_after = true, $echo = true ) {
    global $post;
    extract( $args, EXTR_OVERWRITE );

    echo '<template class="themify-repeater-template">';
        themify_meta_field_repeater_template( $meta_box, array(), '__i__' );
    echo '</template><!-- .themify-repeater-template-->';
    
    $meta_value = isset($meta_value) ? $meta_value : '';
    $meta_value = !is_array( $meta_value ) && !empty($meta_box['show_first']) && true === $meta_box['show_first']  ? array(array()) : $meta_value ;
    echo '<div class="themify-repeater-rows">';
        if( isset( $meta_value ) && is_array( $meta_value ) ) {
            foreach( $meta_value as $id => $values ) {
                themify_meta_field_repeater_template( $meta_box, $values, $id );
            }
        }
    echo '</div><!-- .themify-repeater-rows -->';

    $label = isset( $meta_box['add_new_label'] ) ? $meta_box['add_new_label'] : __( 'Add New', 'themify' );
    echo '<button class="themify-repeater-add button button-secondary">' , $label , '</button>';

    if ( isset( $meta_box['meta']['description'] ) && '' != $meta_box['meta']['description'] ) {
        echo '<span class="themify_field_description">' , $meta_box['meta']['description'] , '</span>';
    }
}

/**
 * Generates Image Radio
 *
 * @param array $args Field settings
 *
 * @since 1.3.2
 * @return string
 */
function themify_meta_field_image_radio( $args ) {
    $meta_box = $args['meta_box'];
    $meta_value = $args['meta_value'];
    extract( $args, EXTR_OVERWRITE );

    $html = '';
    foreach ( $meta_box['meta'] as $option ) {

        if ( ( '' == $meta_value || ! $meta_value || ! isset( $meta_value ) ) && ( isset( $option['selected'] ) && $option['selected'] ) ) {
            $meta_value = $option['value'];
        }

        if ( $meta_value == $option['value'] ) {
            $class = 'selected';
        } else {
            $class = '';
        }

        if(isset($meta_box['show_title'])){
            $title = isset( $option['title'] )? $option['title']: ucwords( str_replace( '-', ' ', $option['value'] ) );
        } else {
            $title = '';
        }

        // Check image src whether absolute url or relative url
        $img_src = ( '' != parse_url( $option['img'], PHP_URL_SCHEME) ) ? $option['img'] : get_template_directory_uri() . '/' . $option['img'];

        $rid = $meta_box['name'] . '-' . esc_attr( $option['value'] );
        $html .= sprintf('
        <div class="tm-radio-option">
            <input type="radio" name="%s" id="%s" value="%s" %s />
            <label for="%s"><img src="%s" alt="%s"/></label>
            <span class="tm-option-title">%s</span>
        </div>
        ',
            $meta_box['name'], $rid, $option['value'], checked( $meta_value, $option['value'], false ),
            $rid,
            $img_src, $title, $title
        );
    }

    if(isset($meta_box['label']) && '' != $meta_box['label'])
        $html = sprintf('<label for="%s">%s %s</label>', esc_attr( $meta_box['name'] ), $html, esc_attr( $meta_box['label'] ));

    $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';

    if( isset( $meta_box['before'] ) ) $html = $meta_box['before'] . $html;
    if( isset( $meta_box['after'] ) )  $html .= $meta_box['after'];

    echo $html;
}

/**
 * Display a hidden input. Value is retrieve from DB, or the "default" parameter if provided.
 */
function themify_meta_field_hidden( $args ) {
    $meta_value = $args['meta_value'];
    if ( isset( $args['meta_box']['default'] ) && empty( $meta_value ) && ! ( $meta_value === 0 || $meta_value === '0' ) ) {
        $meta_value = $args['meta_box']['default'];
    }

    $html = sprintf('<input type="hidden" id="%s" name="%s" value="%s" />',
        esc_attr( $args['meta_box']['name'] ), esc_attr( $args['meta_box']['name'] ), esc_attr( $meta_value ) );

    echo $html;
}
