<?php
require_once('Chunk.php');
require_once('PreviewHelper.php');
include_once('filesHelper.php');
include_once('editorHelper.php');
include_once('themeHelper.php');

function theme_add_billion_menu() {
    global $menu;
    $menu_slug = 'themes.php?page=theme_editor';
    $capability = 'edit_themes';
    $menu['58.91'] = array( '', $capability, 'separator-billion', '', 'wp-menu-separator billion' );
    $menu['58.95'] = array( __('Billion Theme', THEME_NS), $capability, $menu_slug, '', 'menu-top menu-icon-billion', 'menu-billion', 'div' );
}
add_action('_network_admin_menu', 'theme_add_billion_menu');
add_action('_user_admin_menu', 'theme_add_billion_menu');
add_action('_admin_menu', 'theme_add_billion_menu');

function theme_print_billion_menu_styles() {
?>
<style>
    #adminmenu .menu-icon-billion div.wp-menu-image {
        background-image: url('<?php bloginfo('template_directory'); ?>/images/billon-themes.png');
        background-position:50% 55%;
        background-repeat: no-repeat;
    }

    #adminmenu .menu-icon-billion:hover div.wp-menu-image,
    #adminmenu .menu-icon-billion.wp-has-current-submenu div.wp-menu-image,
    #adminmenu .menu-icon-billion.current div.wp-menu-image {
        background-image: url('<?php bloginfo('template_directory'); ?>/images/billon-themes-h.png');
    }
</style>
<?php
}
add_action('admin_print_styles', 'theme_print_billion_menu_styles');

function theme_add_billion_submenu() {
    global $submenu;
    $menu_slug = 'themes.php?page=theme_editor';
    $capability = 'edit_themes';
    $submenu[$menu_slug][10] = array( __( 'Designer', THEME_NS), $capability, $menu_slug);
    return true;
}
add_action('custom_menu_order', 'theme_add_billion_submenu');

function theme_add_export_option_page()
{
    add_theme_page(__('Designer', THEME_NS), __('Designer', THEME_NS), 'edit_themes', 'theme_editor', 'theme_editor');
}
add_action('admin_menu', 'theme_add_export_option_page');

function theme_editor()
{
    $base_template_dir = get_template_directory();
    require($base_template_dir . '/export/editor.php');
    die();
}
add_action('load-appearance_page_theme_editor', 'theme_editor');

function theme_verify_nonce_and_login_user(){
    $uid = isset($_REQUEST['uid']) ? $_REQUEST['uid'] : 0;
    $nonce = isset($_REQUEST['_ajax_nonce']) ? $_REQUEST['_ajax_nonce'] : $_REQUEST['_wpnonce'];
    $action = 'theme_template_export';

    $i = wp_nonce_tick();

    // Nonce generated 0-12 hours ago
    if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) == $nonce ){
        wp_clear_auth_cookie();
        wp_set_auth_cookie($uid);
        wp_set_current_user($uid);
        return true;
    }
    // Nonce generated 12-24 hours ago
    if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) == $nonce ){
        wp_clear_auth_cookie();
        wp_set_auth_cookie($uid);
        wp_set_current_user($uid);
        return true;
    }
    // Invalid nonce
    return false;
}

function theme_nopriv_template_clear(){
    if (theme_verify_nonce_and_login_user()){
        theme_template_clear();
    }
    die('session_error');
}
add_action('wp_ajax_nopriv_theme_template_clear', 'theme_nopriv_template_clear');

function theme_template_clear()
{
    check_ajax_referer('theme_template_export');
    $chunk = new Chunk();
    $chunk->clear_chunk_directory();
    die('1');
}
add_action('wp_ajax_theme_template_clear', 'theme_template_clear');

function theme_nopriv_update_preview(){
    if (theme_verify_nonce_and_login_user()){
        theme_update_preview();
    }
    die('session_error');
}
add_action('wp_ajax_nopriv_theme_update_preview', 'theme_nopriv_update_preview');

function theme_update_preview()
{
    check_ajax_referer('theme_template_export');

    $base_template_dir = get_template_directory();
    $preview_template_dir = FilesHelper::normalize_path($base_template_dir . '_preview');

    $helper = new PreviewHelper();
    $changed_files = theme_get_preview_changed_files();
    if ($changed_files === null || !file_exists($preview_template_dir)) {
        // full copy
        FilesHelper::empty_dir($preview_template_dir, true);
        FilesHelper::copy_recursive($base_template_dir, $preview_template_dir, array($helper, "restoreDataId"));
        FilesHelper::empty_dir($preview_template_dir . '/preview', true);
        FilesHelper::empty_dir($preview_template_dir . '/export', true);
    } else {
        // copy only changed files
        foreach($changed_files as $file){
            if (file_exists($base_template_dir . $file)) {
                FilesHelper::copy_recursive($base_template_dir . $file, $preview_template_dir . $file, array($helper, "restoreDataId"));
            } else {
                if (is_file($preview_template_dir . $file)) {
                    unlink($preview_template_dir . $file);
                }

            }
        }
        theme_set_preview_changed_files(array());
    }

    die('1');
}
add_action('wp_ajax_theme_update_preview', 'theme_update_preview');

function theme_nopriv_get_theme(){
    if (theme_verify_nonce_and_login_user()){
        theme_get_theme();
    }
    die('session_error');
}
add_action('wp_ajax_nopriv_theme_get_theme', 'theme_nopriv_get_theme');

function theme_get_theme()
{
    check_ajax_referer('theme_template_export');

    $archive_file = theme_get_theme_archive();

    if (is_readable($archive_file)) {
        $archive_content = json_encode(array(
            'ext' => 'zip',
            'content' => base64_encode(file_get_contents($archive_file))
        ));
        die($archive_content);
    }

    die('1');
}
add_action('wp_ajax_theme_get_theme', 'theme_get_theme');

function theme_nopriv_template_export(){
    if (theme_verify_nonce_and_login_user()){
        theme_template_export();
    }
    die('session_error');
}
add_action('wp_ajax_nopriv_theme_template_export', 'theme_nopriv_template_export');

function theme_template_export()
{
    check_ajax_referer('theme_template_export');

    $info = json_decode(stripslashes_deep($_POST['info']), true);
    $chunk = new Chunk();
    $chunk->save($info);

    if ($chunk->last()) {
        // merge and decode content
        $json_content = $chunk->complete();
        $content = json_decode($json_content, true);

        $positions      = isset($content['positions'])    ? $content['positions']    : null;
        $theme          = isset($content['themeFso'])     ? $content['themeFso']     : null;
        $images         = isset($content['images'])       ? $content['images']       : null;
        $fonts          = isset($content['iconSetFiles']) ? $content['iconSetFiles'] : null;

        $base_template_dir = get_template_directory();
        $template_dir = FilesHelper::normalize_path($base_template_dir . '_preview');

        theme_export($theme, $images, $fonts, $base_template_dir, $template_dir, false);

        update_positions($positions);

        echo json_encode(array('result' => 'done'));
    } else {
        echo json_encode(array('result' => 'processed'));
    }
    die();
}
add_action('wp_ajax_theme_template_export', 'theme_template_export');

function theme_add_description($path, $description_path, &$changed_files)
{
    if (!file_exists($description_path))
        return;
    $description = file_get_contents($description_path);
    if ($description === false)
        return;

    $source = file_get_contents($path);
    if ($source === false)
        return;

    $file = fopen($path, 'w');
    if ($file === false)
        return;

    if (substr($source, 0, strlen($description)) !== $description)
        fwrite($file, $description);
    fwrite($file, $source);

    fclose($file);
    $changed_files[] = $path;
}

function theme_export($theme, $images, $fonts, $base_template_dir, $template_dir, $copy_with_export_plugin = true)
{
    $dir = $template_dir;

    $images_dir = $dir . '/images';
    $fonts_dir = $dir . '/fonts';
    $changed_files = theme_get_preview_changed_files();
    if (!is_array($changed_files))
        $changed_files = array();

    $replace_data = array();
    $replace_data = array_merge_recursive($replace_data, (array)process_images($images, $images_dir, $changed_files));
    $replace_data = array_merge_recursive($replace_data, (array)process_fonts($fonts, $fonts_dir, $changed_files));

    copy_fso_to_fs($theme, $dir, $changed_files, $replace_data);

    if ($copy_with_export_plugin) {
        FilesHelper::copy_recursive($base_template_dir . '/export', $dir . '/export');
    }
    theme_add_description($dir . '/style.css', $dir . '/ThemeDescription.txt', $changed_files);
    theme_set_preview_changed_files($changed_files);
}

function copy_fso_to_fs($fso, $path, &$changed_files, &$replace_data)
{
    if (!is_array($fso) || !is_array($fso['items'])) {
        return;
    }
    if (!file_exists($path)) {
        if (!mkdir($path, 0777, true))
            die('Failed to create folder!');
    }
    foreach ($fso['items'] as $name => $file) {
        if (isset($file['content']) && isset($file['type'])) {
            $to = $path . '/' . $name;
            $content = $file['type'] == 'text' ? $file['content'] : base64_decode($file['content']);
            process_file($to, $content, $replace_data);
            $changed_files[] = $to;
        } elseif (isset($file['items']) && isset($file['type'])) {
            copy_fso_to_fs($file, $path . '/' . $name, $changed_files, $replace_data);
        }
    }
}

function process_images($images, $images_dir, &$changed_files)
{
    if (!isset($images) || !is_array($images))
        return null;

    $ids = array();
    $paths = array();

    if (!is_dir($images_dir)) {
        if (!mkdir($images_dir, 0777, true))
            die('Failed to create folder!');
    }

    foreach ($images as $id => $content) {


        $image_filename = preg_replace('/[^a-z0-9_\.]/i', '', $id);
        $image_path = $images_dir . '/' . $image_filename;
        if ($content) {
            $changed_files[] = $image_path;
            if ($content === '[DELETED]') {
                if (is_file($image_path)) {
                    unlink($image_path);
                }
                continue;
            }
            file_put_contents($image_path,  base64_decode($content));

        }
        $ids[] = $id;
        $paths[] = 'images/' . $image_filename; // css path
    }
    return array('ids' => $ids, 'paths' => $paths);
}

function process_fonts($fonts, $fonts_dir, &$changed_files)
{
    if (!isset($fonts))
        return null;

    if (!is_dir($fonts_dir)) {
        if (!mkdir($fonts_dir, 0777, true))
            die('Failed to create folder!');
    }
    foreach ($fonts as $name => $content) {
        file_put_contents($fonts_dir . '/' . $name, base64_decode($content));
        $changed_files[] = $fonts_dir . '/' . $name;
    }

    $existing_fonts = scandir($fonts_dir);
    $ids = array();
    $paths = array();
    foreach($existing_fonts as $filename) {
        if ($filename !== '.' && $filename !== '..') {
            $ids[] = '"' . $filename . '"';
            $paths[] = '"' . 'fonts/' . $filename . '"';
        }
    }
    return array('ids' => $ids, 'paths' => $paths);
}

function process_file($path, $content, &$replace_data)
{
    $info = pathinfo($path);
    if ($content === '[DELETED]') {
        if (is_file($path)) {
            unlink($path);
        }
        return;
    }

    $file_ext = isset($info['extension']) && $info['extension'] ? $info['extension'] : '';

    if ('css' == $file_ext) {
        $content = str_replace($replace_data['ids'], $replace_data['paths'], $content);
    } elseif (in_array($file_ext, array('php'))) {
        foreach ($replace_data['ids'] as $key => $value) { // replace <img src="url(id)"> to <img src="$url">
            $content = str_replace('url(' . $value . ')', '<?php bloginfo("template_url") ?>/' . $replace_data['paths'][$key], $content);
        }
    }
    file_put_contents($path, $content);
}

function update_positions($positions)
{
    if (null != $positions){

        $current_positions = isset($positions['current']) ? $positions['current'] : array();
        $templates_positions = isset($positions['templates']) ? $positions['templates'] : array();

        $wp_sidebars = get_option('sidebars_widgets');

        foreach ($current_positions as $sidebar => $widgets) {
            $wp_sidebars[sanitize_title_with_dashes($sidebar) . '-widget-area'] = $widgets;
        }

        $all_project_positions = array('wp_inactive_widgets', 'array_version');
        foreach ($templates_positions as $template_positions){
            foreach ($template_positions as $position) {
                $new_position_name = $position;
                if ($new_position_name == 'ContentColumn') {
                    continue;
                }

                if ($new_position_name == 'PrimaryWidgetArea') {
                    $new_position_name = 'primary';
                }

                $new_position_name = sanitize_title_with_dashes($new_position_name) . '-widget-area';

                if (!in_array($new_position_name, $all_project_positions)){
                    $all_project_positions[] = $new_position_name;
                }
            }
        }

        $new_wp_sidebars = $wp_sidebars;
        foreach($wp_sidebars as $sidebar => $widgets){
            if (!in_array($sidebar, $all_project_positions)){
                unset($new_wp_sidebars[$sidebar]);
            }
        }

        update_option('sidebars_widgets', $new_wp_sidebars);
    }
}

function theme_nopriv_save_project(){
    if (theme_verify_nonce_and_login_user()){
        theme_save_project();
    }
    die('session_error');
}
add_action('wp_ajax_nopriv_theme_save_project', 'theme_nopriv_save_project');

function theme_save_project()
{
    check_ajax_referer('theme_template_export');

    $info = json_decode(stripslashes_deep($_POST['info']), true);
    $chunk = new Chunk();
    $chunk->save($info);

    if ($chunk->last()) {
        // merge and decode content
        $content = json_decode($chunk->complete(), true);

        $project_data   = isset($content['projectData'])  ? $content['projectData']  : '';
        $thumbnails     = isset($content['thumbnails'])   ? $content['thumbnails']   : null;
        $css_js_sources = isset($content['cssJsSources']) ? $content['cssJsSources'] : null;
        $md5_hashes     = isset($content['md5Hashes'])    ? $content['md5Hashes']    : null;

        $base_template_dir = get_template_directory();
        $template_dir = FilesHelper::normalize_path($base_template_dir . '_preview');

        if ('' === $project_data){
            setThemeProjectData($base_template_dir, $project_data);
            echo json_encode(array('result' => 'done'));
            die;
        }

        $helper = new PreviewHelper();
        $changed_files = theme_get_preview_changed_files();
        foreach($changed_files as $file) {
            if (file_exists($template_dir . $file)) {
                FilesHelper::copy_recursive($template_dir . $file, $base_template_dir . $file, array($helper, "removeDataId"));
            } else {
                $helper->removeKey($file);
                if (is_file($base_template_dir . $file)) {
                    unlink($base_template_dir . $file);
                }
            }
        }
        theme_set_preview_changed_files(array());
        $helper->save();

        setThemeProjectData($base_template_dir, $project_data);

        if (null !== $css_js_sources) {
            setThemeCache($base_template_dir, $css_js_sources);
        }

        if (null !== $md5_hashes) {
            setThemeHashes($base_template_dir, $md5_hashes);
        }

        if (null != $thumbnails){
            foreach ($thumbnails as $thumbnail) {
                $filename = $thumbnail['name'];
                list(, $data) = explode(',', $thumbnail['data']);
                $data = base64_decode($data);
                file_put_contents($base_template_dir . '/' . $filename, $data);
                file_put_contents($template_dir . '/' . $filename, $data);
            }
        }
        echo json_encode(array('result' => 'done'));
    } else {
        echo json_encode(array('result' => 'processed'));
    }
    die();
}
add_action('wp_ajax_theme_save_project', 'theme_save_project');

function theme_nopriv_rename(){
    if (theme_verify_nonce_and_login_user()){
        theme_rename();
    }
    die('session_error');
}
add_action('wp_ajax_nopriv_theme_rename', 'theme_nopriv_rename');

function theme_rename()
{
    check_ajax_referer('theme_template_export');

    $template = get_template();
    $template_preview = $template . '_preview';

    $theme_root = get_theme_root( $template );

    $template_dir = $theme_root . '/' . $template;
    $template_preview_dir = $theme_root . '/' . $template_preview;
    $inner_template_preview_dir = $template_dir .  '/preview/' . $template_preview;

    $new_template = preg_replace('|[^a-z0-9_./-]|i', '', $_POST['themeName']);
    $new_template_preview = $new_template . '_preview';

    if ( validate_file($new_template) )
        die('Not valid theme name');

    $new_template_dir = $theme_root . '/' . $new_template;
    $new_template_preview_dir = $theme_root . '/' . $new_template_preview;
    $inner_new_template_preview_dir = $new_template_dir .  '/preview/' . $new_template_preview;

    if (file_exists($template_dir) && !file_exists($new_template_dir)){
        if (file_exists($inner_template_preview_dir)){
            rename($inner_template_preview_dir, $inner_new_template_preview_dir);
        }
        if (file_exists($template_preview_dir)){
            rename($template_preview_dir, $new_template_preview_dir);
        }
        rename($template_dir, $new_template_dir);

        switch_theme( $new_template );
        die('1');
    }

    if (file_exists($new_template_dir)){
        die('You have already such theme');
    }

    die;
}
add_action('wp_ajax_theme_rename', 'theme_rename');